我正在设置需要创建客户端的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;
}
}
答案 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;
}
中传递的方式。