ReactJS и веб-сокеты: прослушивание событий трансляции сервера во внешнем интерфейсе

Я кодирую приложение чата, используя ReactJS, Socket.io, and NodeJS. Я завершил базовую часть подключения к сокету, и когда я ввожу сообщение и нажимаю ввод, сообщение отправляется на серверную часть. Теперь я хочу, чтобы после того, как кто-либо добавил сообщение (несколько вкладок), сообщение транслировалось всем остальным клиентам, кроме того, кто его инициировал, и должно отображаться в списке сообщений. Я передаю сообщение всем клиентам с сервера, когда сообщение получено от определенного клиента, но не знаю, где его поймать на моем интерфейсе в приложении реагирования.

Позвольте мне пройтись по коду:

App.js — Мое приложение состоит из 3 основных компонентов: Пользователи (список пользователей), Сообщения (список сообщений, в котором будут отображаться все сообщения для всех онлайн-пользователей) и AddMessage (содержит текстовое поле и кнопку для добавления сообщения)

class App extends Component {
  render() {
    const { classes } = this.props;
    return (
      <div className = "App">
        {/* <UserNameInp /> */}
        <section className = {classes.usersSection}>
          <Users />
        </section>
        <section className = {classes.messagesSection}>
          <section className = {classes.messagesStyle}>
            <Messages />
          </section>
          <section className = {classes.addMessageStyle}>
            <AddMessage />
          </section>
        </section>
      </div>
    );
  }
} 

действия.js: сохраняет действия addMessageToList. Когда добавляется новое сообщение, я отправляю его на сервер, используя socket.emit

export var addMessageToList = messageText => {
  let messageDtls = {};
  messageDtls.messageText = messageText;
  messageDtls.messageAuthor = "You";  //just for testing
  messageDtls.messageID = "You" + messageText;  //just for testing
  socket.emit("addmessage", messageDtls);

  return {
    type: actionTypes.ADD_MESSAGE_TO_LIST,
    payLoad: { messageDtls: messageDtls }
  };
};

редуктор.js — Редуктор содержит messagesList как значение состояния, которое содержит все сообщения от всех пользователей, включая текущего.

var initState = {
  messagesList: []
};

var addMessageToList = (state, action) => {
  return {
    ...state,
    messagesList: [...state.messagesList, action.payLoad.messageDtls]
  };
};

var reducer = (state = initState, action) => {
  switch (action.type) {
    case actionTypes.ADD_MESSAGE_TO_LIST:
      return addMessageToList(state, action);
    default:
      return state;
  }
};
export default reducer;

Сообщения.js — компонент отображает каждый компонент сообщения, используя карту в виде списка. Список сообщений поступает из хранилища избыточности.

class Messages extends Component {
  render() {
    let messages = null;
    messages =
      this.props.messagesList &&
      this.props.messagesList.map((ele, index) => {
        return (
          <Message
            key = {index}
            messageAuthor = {ele.messageAuthor}
            messageText = {ele.messageText}
          />
        );
      });

    const { classes } = this.props;
    return (
      <Card className = {classes.card} raised = {true}>
        <span>Messages</span>
        <CardContent className = {classes.cardContent}>{messages}</CardContent>
      </Card>
    );
  }
}

var mapStateToProps = state => {
  return {
    messagesList: state.messagesList
  };
};

var mapDispatchToProps = dispatch => {
  return {
    addMessageToList: messageText =>
      dispatch(actions.addMessageToList(messageText))
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(withStyles(styles)(Messages));

AddMessage.js — компонент, в котором действие addMessageToList отправляется при нажатии кнопки, чтобы сообщение можно было добавить в состояние messagesList.

class AddMessage extends Component {
  state = {
    value: ""
  };
  handleChangeEvent = event => {
    this.setState({
      value: event.target.value
    });
  };

  onEnterKeyPress = event => {
    this.props.addMessageToList(this.state.value);
    this.setState({
      value: ""
    });
  };
  render() {
    const { classes } = this.props;
    return (
      <Paper className = {classes.root} elevation = {1}>
        <InputBase
          className = {classes.input}
          placeholder = "Message"
          onChange = {this.handleChangeEvent}
          value = {this.state.value}
          // onKeyPress = {this.onEnterKeyPress}
        />
        <IconButton
          className = {classes.iconButton}
          aria-label = "Enter"
          onClick = {this.onEnterKeyPress}
          disabled = {this.state.value === "" ? true : false}
        >
          <ChatIcon />
        </IconButton>
      </Paper>
    );
  }
}

var mapDispatchToProps = dispatch => {
  return {
    addMessageToList: messageText =>
      dispatch(actions.addMessageToList(messageText))
  };
};

export default connect(
  null,
  mapDispatchToProps
)(withStyles(styles)(AddMessage));

Серверная часть App.js — выдержка из файла App.js, где при соединении с сокетом я прослушиваю событие «addmessage» и транслирую событие «messagesadded».

io.on("connection", socket => {
  console.info("User connected");
  socket.on("addmessage", message => {
    // messagesRecieved = message.messageText;
    console.info("Message received : " + message.messageText);
    socket.broadcast.emit("messagesadded", message);
  });
});

Теперь я не уверен, где в моем коде React я должен слушать событие «messagesadded», транслируемое с сервера. Это должно быть похоже на непрерывное прослушивание, чтобы всякий раз, когда сообщение передается, я мог снова отправить действие addMessageToList, и оно обновило состояние messagesList и снова отобразило компонент Messages.

Спасибо.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
1 853
1

Ответы 1

Вы должны прослушивать событие сокета в componentDidMount().

componentDidMount(){
 socket.on("messagesadded", message => {
  //dispatch action
});
}

Спасибо за ответ. componentDidMount() какого компонента? Я пробовал это уже в сообщениях, но это какая-то бесконечная отправка. Более того, меня беспокоит то, что если я прослушаю его в любом из компонентов компонента componentDidMount(), для этого для вызова компонент должен быть смонтирован более чем n над. Что, если пользователь вводит сообщение, а затем сидит без дела и в другом окне, пользователь вводит и сообщение передается с сервера, componentDidMount() не сработает автоматически.

Shantanu Tomar 06.02.2019 11:52

@ShantanuTomar в вашем файле Сообщения.js. Вы можете реорганизовать свой код, преобразовав некоторые компоненты в компоненты без сохранения состояния. и сохраните Сообщения.js как компонент с полным состоянием. Вы можете проверить ввод (в компоненте добавления сообщения). Отправляйте сообщение отправки только тогда, когда вы нажимаете кнопку ввода при нажатии кнопки отправки, тогда это не будет проблемой.

TRomesh 06.02.2019 12:10

Прошу прощения, но мне непонятно. Сообщения по-прежнему являются компонентом с отслеживанием состояния. И я не уверен, как здесь проявляется компонент AddMessage. Пожалуйста, если вы можете уточнить это, был бы признателен.

Shantanu Tomar 06.02.2019 14:01

Другие вопросы по теме