Так как вы уже используете redux, лучше сделать для socket.io диспетчерские действия при редукции для вас, вы можете использовать redux saga так же, как описано в этой статье , или вы можете использовать эту реализацию без saga, но вам нужно иметь redux-thunk middleware:
1 - Создать файл, скажем, lib/socket.js
затем внутри этого файла создайте socket.io
клиент, который будет вызывать его socket
, и создайте initSocketIO
функцию, в которой вы можете запускать любые избыточные действия в ответ на socket.io:
import socket_io from "socket.io-client";
// our socket.io client
export const socket = socket_io("http://localhost:5000");
/**
* init socket.io redux action
* @return {Function}
*/
export const initSocketIO = () => (dispatch, getState) => {
// connect
socket.on('connect', () => dispatch(appActions.socketConnected()));
// disconnect
socket.on('disconnect', () => dispatch(appActions.socketDisconnected()));
// message
socket.on('message', message => {
dispatch(conversationActions.addOrUpdateMessage(message.conversationId, message.id, message));
socket.emit("message-read", {conversationId: message.conversationId});
});
// message
socket.on('notifications', ({totalUnread, notification}) => {
dispatch(recentActions.addOrUpdateNotification(notification));
dispatch(recentActions.setTotalUnreadNotifications(totalUnread));
});
};
2 - тогда внутри вашего App
компонента вызовите это действие, как только ваш App
смонтирован:
import React, {Component} from "react";
import {initSocketIO} from "./lib/socket.js";
export class App extends Component {
constructor(props) {
super(props);
this.store = configureStore();
}
componentDidMount() {
// init socket io
this.store.dispatch(initSocketIO());
}
// ... whatever
}
3 - теперь вы также можете запустить любое действие socket.io из любого компонента, используя это:
import React, {Component} from "react";
import {socket} from "./lib/socket.js"
MyComponent extends Components {
myMethod = () => socket.emit("message",{text: "message"});
}
или из любого редукционного действия с использованием thunk, например:
export const sendMessageAction = (text) => dispatch => {
socket.emit("my message",{text});
dispatch({type: "NEW_MESSAGE_SENT",payload:{text}});
}
Примечания:
1 - это будет отлично работать, но все же я предпочитаю метод redux-saga для управления любыми побочными эффектами, такими как API и socket.io.
2 - В ваших компонентах вам не нужно связывать методы компонентов с this
, просто используйте функции стрелок, например:
myMethod = () => {
// you can use "this" here
}
render = (){
return <Launcher onMessageWasSent={this.myMethod} />
}