长时间运行的进程在React + Redux应用程序中的位置在哪里?

Dav*_*ver 26 javascript reactjs redux

长期运行的流程应该在react + redux应用程序中"活动"?

举一个简单的例子,考虑一个通过websocket发送和接收消息的类:

class WebsocketStreamer {
  sendMessage(message) {
    this.socket.send(…);
  }

  onMessageReceive(event) {
    this.dispatch({
        type: "STREAMER_RECV",
        message: event.data,
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

如何管理这个类的生命周期?

我的第一直觉是保持store:

var stores = {
  streamer: function(state={}, action) {
    if (action.type == "@@INIT")
      return { streamer: new WebsocketStreamer() }
    if (action.type == "STREAMER_SEND")
      state.streamer.sendMessage(action.message)
    return state;
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,除了有点奇怪之外,还没有办法WebsocketStreamer访问该dispatch()函数,并且它会破坏热重新加载.

另一个可能的解决方案是将其保持在某个地方:

const streamer = new WebsocketStreamer();
Run Code Online (Sandbox Code Playgroud)

但这具有明显的可测试性含义,并且也打破了热重新加载.

那么,一个长期运行的进程应该放在react + redux应用程序中?

注意:我意识到这个简单的例子可以只使用商店+动作提供者构建.但我特别想知道在它们存在的情况下应该存在长期存在的过程.

Vic*_*lev 19

根据我的经验,有两种选择.首先,您可以将商店传递给任何非Redux代码并从此处调度操作.我用套接字连接做了这个,一切都很好.其次,如果你需要套接字或者用redux动作改变什么,那么将连接和它的管理放在自定义中间件中似乎是一个好主意.您将可以访问商店API,并将获得所有调度操作的通知,因此可以执行您需要的任何操作.

  • 两者都是有效的解决方 (13认同)

Chr*_*tin 2

我正在用网络套接字做类似的事情。就我而言,我只是将 websocket 客户端包装在一个呈现 null 的 React 组件中,并将其注入到尽可能靠近根的位置。

<App>
    <WebSocketClientThingy handlers={configuredHandlers}/>
    ....
</App>
Run Code Online (Sandbox Code Playgroud)

这是一个简单的例子。虽然很天真,但还是把事情做好吧。

https://github.com/trbngr/react-example-pusher

快速说明:Websocket 不在商店中。它就在那里并发布操作。

编辑:我决定探索将客户端(长期存在的对象)设置为全局状态。我得说我很喜欢这种方法。

https://github.com/trbngr/react-example-pusher/tree/client_as_state