【问题标题】:Where to store Class instance for reusability in Redux?在 Redux 中在哪里存储类实例以实现可重用性?
【发布时间】:2019-01-20 17:51:50
【问题描述】:

我正在尝试在我的 React/Redux/redux 传奇应用程序中通过 Pusher 实现消息传递库 Chatkit,我是 Redux 的新手。连接chatkit的代码如下:

const chatManager = new ChatManager({
    instanceLocator: 'v1:us1:80215247-1df3-4956-8ba8-9744ffd12161',
    userId: 'sarah',
    tokenProvider: new TokenProvider({ url: 'your.auth.url' })
})

chatManager.connect()
    .then(currentUser => {
        console.log('Successful connection', currentUser)
    })
    .catch(err => {
        console.log('Error on connection', err)
    })

我需要全局存储 chatManager 和 currentUser 对象(它们是具有附加功能的复杂类的实例),以便我以后可以再次使用它们来加入房间、订阅事件等。

我的第一个想法是我应该将它存储在 Redux 中,因为它现在是我的“全局存储”,但后来我意识到它可能无法正常工作,因为它不是我从存储中取回的原始对象,它可能是一个克隆。然后我读到,显然只有普通对象应该存储在 Redux 中。

那么,不是普通对象但需要全局存储的东西在哪里?我不想将它们放在 window 对象上,因为我可能会将其转换为 React Native 应用程序,而且它看起来很乱。

【问题讨论】:

    标签: reactjs redux redux-saga


    【解决方案1】:

    根据Redux FAQ entry on storing "connection"-type objects

    中间件是 Redux 应用程序中持续连接(如 websockets)的正确位置,原因如下:

    • 中间件存在于应用程序的整个生命周期中
    • 与商店本身一样,您可能只需要整个应用程序都可以使用的给定连接的单个实例
    • 中间件可以看到所有已调度的动作和调度动作本身。这意味着中间件可以采取已调度的操作并将其转换为通过 websocket 发送的消息,并在通过 websocket 接收到消息时调度新的操作。
    • websocket 连接实例不可序列化,因此它本身不属于 store 状态​

    编辑

    这是我的“示例套接字中间件”示例,已更新为延迟创建套接字,直到它看到登录操作:

    const createMySocketMiddleware = (url) => {
        let socket;
    
        return storeAPI => next => action => {
            switch(action.type) {
                case "LOGIN" : {
                    socket = createMyWebsocket(url);
    
                    socket.on("message", (message) => {
                        storeAPI.dispatch({
                            type : "SOCKET_MESSAGE_RECEIVED",
                            payload : message
                        });
                    });
                    break;
                }
                case "SEND_WEBSOCKET_MESSAGE": {
                    socket.send(action.payload);
                    return;
                }
            }
    
            return next(action);
        }
    }
    

    【讨论】:

    • 谢谢,我想这是有道理的。我将不得不学习如何制作中间件!
    • 再问一个问题。该示例在创建连接器时对其进行实例化。在我的应用程序中,直到用户登录后才会创建连接器。是否有可能创建中间件,它在看到登录操作(当前使用 redux-saga 处理)之前什么都不做,然后实例化连接器并处理其他从那时起与聊天相关的操作?我假设所有中间件都必须从一开始就应用,它不能随意应用和“未应用”到 redux?
    • 当然,这很容易做到。我已经相应地更新了我的答案。根据最后一个问题:通常,一旦您创建了应用程序,中间件就会被修复,但我已经看到一些中间件可以让您在运行时动态修改中间件列表(有关示例,请参阅 my list of existing middlewares)。
    • 马克,只是想再次感谢您的出色回答,我已经多次提及。但是,我只是注意到在这一行中 - return storeAPI => action => next => - 你把 action 和 next 参数放错了方向。我一直得到“下一个未定义”,直到我意识到它与 redux 网站示例有什么不同:)
    猜你喜欢
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    相关资源
    最近更新 更多