我一直在阅读关于将WebSocket集成到React/Redux应用程序的最佳方法,并且我找到了答案,但是沿着“websocket实现的最佳位置通常是中间件”的句子。Redux + Websockets:为什么使用中间件来管理这个?
我的问题是为什么这是首选?这样做与设置外部应用程序级React容器(例如componentWillMount
)中的websocket /听众分派操作有什么好处?
这似乎就像在应用程序的整个生命周期持续期间等效,等等。我在这里错过了什么?
我一直在阅读关于将WebSocket集成到React/Redux应用程序的最佳方法,并且我找到了答案,但是沿着“websocket实现的最佳位置通常是中间件”的句子。Redux + Websockets:为什么使用中间件来管理这个?
我的问题是为什么这是首选?这样做与设置外部应用程序级React容器(例如componentWillMount
)中的websocket /听众分派操作有什么好处?
这似乎就像在应用程序的整个生命周期持续期间等效,等等。我在这里错过了什么?
有几个专家将这种逻辑放在中间件中而不是实际的组件中。
在我看来,主要的原因是:
WebSocket
否则你会 需要,这将是 独立商店的连接的全局声明,换句话说,不是的一部分流程图如下:redux
流程。redux
流量。总而言之,没有什么特别的理由可以说明中间件使用web-sockets,使用中间件通常具有很大的优势。
编辑
作为随访到您的评论
建议你将如何管理,你可能需要一个 特定组件来初始化一个WebSocket连接,但要 管理是否已经是一个案例连接,等等......它会像 一样简单,因为在商店中有一个标志表示它已连接,或者是 还有更好的方法吗?
正如我所说,我不会初始化一个组件内的Web套接字连接,而是我会在我的应用程序的入口点执行它。例如index.js
。
如果您的问题是确保在已有连接时不尝试连接,那么可以在创建store
时初始化所有应用程序数据时调用该方法的简单方法传递一个回调,通过dispatch
进行渲染并更新store
。
一个简单的例子(记住,这是一个伪代码):
我们的编程入手方法:
export function socketStart(store, callback) {
// this is only a pseudo code!
// register to server -> client events
_socketClient.someFunction = (data) => {
store.dispatch({ type: "Server_Invoked_Some_Function", data });
}
_socketClient.someFunction2 = (data) => {
store.dispatch({ type: "Server_Invoked_Some_Function2", data });
}
// connect to the server via the web-socket client API
_socketClient.connect(() => callback());
}
我们可以在index.js
文件中使用它:
let store = createStore(
// your reducers here...
// ...
applyMiddleware(socketMiddleware) // our web socket middleware
)
// the callback will invoked only if the connection was successful
// the React-Dom's render function is our callback in this case
socketStart(store,() => { render(<App />, document.getElementById("root")); });
使用中间件,您可以轻松地在Redux和Web Socket之间展开/中继消息。此外,您可以使用不带React的Redux中间件,这意味着您可以在服务器端代码上使用Redux编写API(可能使用Redux传奇)。
我同意生命周期管理作为React组件比Redux中间件更容易。但是如果你想重新连接(销毁/重新创建),你需要使用key
道具来让调解者将它视为一个新对象,这有点奇怪。
您可以看看,它将Web Socket消息展开成Redux操作,并将Redux操作中继到Web Socket。
在您的Web套接字服务器,您发送的动作:
ws.on('connection', conn => {
conn.send(JSON.stringify({
type: 'GREETING',
payload: { now: Date.now() }
}));
});
你会得到你的终极版减速器GREETING
行动。反之亦然,当你想传递给网络插座一个动作,你标记你的行动meta.send
与true
:
this.props.dispatch({
type: 'SIGN_IN',
meta: { send: true },
payload: { authToken: '...' }
});
这都有道理,谢谢!这里最大的原因似乎是,作为中间件,它将可以访问整个商店,使用顶级组件进行连接是不可用的(或者是奇怪的/架构上的奇怪)。 你会如何建议管理一个案例,你可能想要一个特定的组件来初始化一个websocket连接,但想要管理它是否已经连接,等等......它就像在商店中有一个标志一样简单它是连接还是有更好的方法? – kasceled
首先,我不会初始化组件内的websocket连接,而是在我的应用程序的入口点执行它(例如'index.js')。如果你关心的是确保当你已经建立连接时你不会尝试连接,那么当你创建'store'时调用一个简单的连接方法,并且在它的回调函数中你可以渲染应用程序。我会用一个简单的例子更新答案 –