如何在redux中存储客户端?

时间:2017-01-13 03:33:35

标签: reactjs redux react-redux redux-thunk

我正在设置需要创建客户端的redux应用程序。初始化之后,客户端具有需要根据特定操作调用的侦听器和API。

因此我需要保留客户端的实例。现在,我把它保存在州里。是吗?

所以我有以下redux动作创建者,但是当我想发送消息时,我需要调用client.say(...)API。

但是我应该从哪里获取客户端对象?我应该从州检索客户端对象吗?我的理解是,这是一种redux反模式。使用redux执行此操作的正确方法是什么?

更奇怪的是 - 如果消息实际上没有改变状态,那么该消息是否应被视为动作创建者?

行动:

// actions.js

import irc from 'irc';

export const CLIENT_INITIALIZE = 'CLIENT_INITIALIZE';
export const CLIENT_MESSAGE_RECEIVED = 'CLIENT_MESSAGE_RECEIVED';
export const CLIENT_MESSAGE_SEND = 'CLIENT_MESSAGE_SEND';

export function messageReceived(from, to, body) {
  return {
    type: CLIENT_MESSAGE_RECEIVED,
    from: from,
    to: to,
    body: body,
  };
};

export function clientSendMessage(to, body) {
  client.say(...); // <--- where to get client from?
  return {
    type: CLIENT_MESSAGE_SEND,
    to: to,
    body: body,
  };
};

export function clientInitialize() {
  return (dispatch) => {
    const client = new irc.Client('chat.freenode.net', 'react');

    dispatch({
      type: CLIENT_INITIALIZE,
      client: client,
    });

    client.addListener('message', (from, to, body) => {
      console.log(body);
      dispatch(messageReceived(from, to, body));
    });
  };
};

这是减速器:

// reducer.js
import { CLIENT_MESSAGE_RECEIVED, CLIENT_INITIALIZE } from '../actions/client';
import irc from 'irc';

export default function client(state: Object = { client: null, channels: {} }, action: Object) {
  switch (action.type) {
    case CLIENT_MESSAGE_RECEIVED:
      return {
        ...state,
        channels: {
          ...state.channels,
          [action.to]: [
            // an array of messages
            ...state.channels[action.to],
            // append new message
            {
              to: action.to,
              from: action.from,
              body: action.body,
            }
          ]
        }
      };

    case CLIENT_JOIN_CHANNEL:
      return {
        ...state,
        channels: {
          ...state.channels,
          [action.channel]: [],
        }
      };

    case CLIENT_INITIALIZE:
      return {
        ...state,
        client: action.client,
      };
    default:
      return state;
  }
}

1 个答案:

答案 0 :(得分:1)

使用中间件将客户端对象注入动作创建者! :)

const client = new MyClient();

const store = createStore(
  combineReducers({
    ...
  }),
  applyMiddleware(clientMiddleware(client))
);

然后应用它:

export function actionCreator() {
  return {
    promise: client => {
      return client.doSomethingPromisey();
    }
  };
}

然后你可以在动作创作者中使用它:

dispatch

这主要是从react-redux-universal-hot-example boilerplate project改编的。我删除了允许您定义开始,成功和失败操作的抽象,用于创建this abstraction in action creators

如果您的客户端不是异步的,您可以调整此代码以简单地传入客户端,类似于redux-thunk在.carousel-inner .item { opacity: 0; transition: none; transform: translate3d(0,0,0) !important; } .carousel-inner .active { transition: opacity 1s ease-in-out; opacity: 1; } 中传递的方式。