【问题标题】:Where to store socket connection in react-redux?react-redux 在哪里存储套接字连接?
【发布时间】:2018-04-09 20:31:47
【问题描述】:

尝试了两种方法:

  1. 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 为空。

  1. 将所有逻辑放入reducer,但结果是:组件被渲染为空道具(未定义的属性),并且在我在控制台日志中看到建立连接后,组件已经被渲染。

如何处理这样的问题?感谢您的任何建议。

【问题讨论】:

    标签: reactjs react-redux phoenix-framework phoenix-channels


    【解决方案1】:

    我发现可行的方法是像这样为套接字设置自己的中间件。

    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。

    【讨论】:

    • 谢谢马克,实际上我使用了我的第一种方法,但我没有在同一个组件中等待道具,而是将其分开,现在看起来像:第一个组件负责连接,并显示结果在下一个。
    • 谢谢,你真的帮了大忙!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 2013-12-15
    相关资源
    最近更新 更多