ReactJS и Websockets: прослушивание событий вещания сервера на Frontend - PullRequest
0 голосов
/ 06 февраля 2019

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

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

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

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>
    );
  }
} 

actions.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 }
  };
};

reducer.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;

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

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: ""
  };
  handleChange = 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.handleChange}
          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));

Backend App.js - Извлечение из файла App.js, где при соединении с сокетом я прослушиваю событие 'addmessage' и транслирую событие emit 'messagesadded'.

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

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

Спасибо.

1 Ответ

0 голосов
/ 06 февраля 2019

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

componentDidMount(){
 socket.on("messagesadded", message => {
  //dispatch action
});
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...