Где хранить сокетное соединение в Reaction-Redux?

Пробовал двумя способами:

  1. вызов connectToServer() от создателя действия внутри Starter компонент в componentDidMount(); и отправить как это:

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

Затем я получаю состояние при помощи mapStateToProps connect, В результате компонент вызывается четыре раза, а реквизиты пусты в результате.

  1. поместите всю логику в редуктор, но результат таков: компонент отображается с пустыми подпорками (неопределенные свойства) и через мгновение после того, как я вижу в журналах консоли, что соединение установлено, но компонент уже отрендерен.

Как бороться с такой проблемой? Спасибо за любые предложения.

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

Примером проекта является ReduxSocketIO по адресу https://github.com/jmarkstevens/ReactPatterns.

Другие вопросы по тегам