在 react-redux 中哪里存储套接字连接?
Where to store socket connection in react-redux?
尝试了两种方式:
在 componentDidMount();
的 Starter
组件中从动作创建者调用 connectToServer()
并像这样发送:
let socket = new Socket('ws://address/socket');
socket.connect();
dispatch({
type: Constants.SESSION_SAVE_SOCKET,
socket: socket,
});
const lobbyChannel = socket.channel('lobby');
lobbyChannel.join()
.receive('ok', () => {
dispatch({
type: Constants.SESSION_LOBBYCHANNEL_RECEIVE_OK,
});
dispatch({
type: Constants.SESSION_SAVE_LOBBYCHANNEL,
lobbyChannel: lobbyChannel,
});
}).receive('error', (payload) => {
dispatch({
type: Constants.SESSION_LOBBYCHANNEL_RECEIVE_ERROR,
});
});
接下来我通过 redux 的 mapStateToProps connect
接收状态。
结果是组件被调用了四次,结果 props 为空。
- 将所有逻辑放入 reducer,但结果是:组件使用空 props(未定义的属性)呈现,并且在我在控制台日志中看到连接已建立但组件已经呈现后的那一刻。
如何处理这样的问题?感谢您的任何建议。
我发现可行的方法是像这样为套接字设置您自己的中间件。
import {createStore, applyMiddleware} from 'redux';
import startWs, {wsMiddleware} from './ws.api';
function handleData(state = {data1: {}}, action) {
switch (action.type) {
case 'ApiGotData': return Object.assign({}, state, {data1: action.data});
default: return state;
}
}
const store = createStore(handleData, applyMiddleware(wsMiddleware));
startWs(store);
export default store;
import * as Actions from './Actions';
var socket = null;
const newData = {
'React version': '15',
'Project': 'Redux with socket.io',
'currentDateTime': new Date().toLocaleString()
};
export function wsMiddleware() {
return (next) => (action) => {
if (socket && action.type === 'ApiGetData') {
console.log('ApiGetData');
socket.emit('client:GetData', {});
} else if (socket && action.type === 'ApiSetData') {
console.log('ApiSetData');
socket.emit('client:SetData', action.data);
}
return next(action);
};
}
export default function (store) {
socket = new io();
socket.on('server:GetDataDone', (data) => {
console.log('GetDataDone');
store.dispatch(Actions.apiGotData(data));
});
socket.on('server:SetDataDone', () => {
console.log('SetDataDone');
store.dispatch(Actions.apiGetData());
});
store.dispatch(Actions.apiSetData(newData));
}
项目示例是 https://github.com/jmarkstevens/ReactPatterns 的 ReduxSocketIO。
尝试了两种方式:
在
componentDidMount();
的Starter
组件中从动作创建者调用connectToServer()
并像这样发送:let socket = new Socket('ws://address/socket'); socket.connect(); dispatch({ type: Constants.SESSION_SAVE_SOCKET, socket: socket, }); const lobbyChannel = socket.channel('lobby'); lobbyChannel.join() .receive('ok', () => { dispatch({ type: Constants.SESSION_LOBBYCHANNEL_RECEIVE_OK, }); dispatch({ type: Constants.SESSION_SAVE_LOBBYCHANNEL, lobbyChannel: lobbyChannel, }); }).receive('error', (payload) => { dispatch({ type: Constants.SESSION_LOBBYCHANNEL_RECEIVE_ERROR, }); });
接下来我通过 redux 的 mapStateToProps connect
接收状态。
结果是组件被调用了四次,结果 props 为空。
- 将所有逻辑放入 reducer,但结果是:组件使用空 props(未定义的属性)呈现,并且在我在控制台日志中看到连接已建立但组件已经呈现后的那一刻。
如何处理这样的问题?感谢您的任何建议。
我发现可行的方法是像这样为套接字设置您自己的中间件。
import {createStore, applyMiddleware} from 'redux';
import startWs, {wsMiddleware} from './ws.api';
function handleData(state = {data1: {}}, action) {
switch (action.type) {
case 'ApiGotData': return Object.assign({}, state, {data1: action.data});
default: return state;
}
}
const store = createStore(handleData, applyMiddleware(wsMiddleware));
startWs(store);
export default store;
import * as Actions from './Actions';
var socket = null;
const newData = {
'React version': '15',
'Project': 'Redux with socket.io',
'currentDateTime': new Date().toLocaleString()
};
export function wsMiddleware() {
return (next) => (action) => {
if (socket && action.type === 'ApiGetData') {
console.log('ApiGetData');
socket.emit('client:GetData', {});
} else if (socket && action.type === 'ApiSetData') {
console.log('ApiSetData');
socket.emit('client:SetData', action.data);
}
return next(action);
};
}
export default function (store) {
socket = new io();
socket.on('server:GetDataDone', (data) => {
console.log('GetDataDone');
store.dispatch(Actions.apiGotData(data));
});
socket.on('server:SetDataDone', () => {
console.log('SetDataDone');
store.dispatch(Actions.apiGetData());
});
store.dispatch(Actions.apiSetData(newData));
}
项目示例是 https://github.com/jmarkstevens/ReactPatterns 的 ReduxSocketIO。