Я кодирую приложение чата, используя 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.
Спасибо.