我在 React 应用程序中使用 Paho MQTT Javascript 库来连接到 MQTT 服务器。一切工作正常,但我想为用户提供一个选项,通过单击按钮手动断开与服务器的连接。
假设连接
const client = new Paho.Client(...)
在一个页面,而调用断开连接的按钮可能在另一个页面,那么如何将客户端对象持久化并在另一个页面中使用来调用client.disconnect()
?
我希望我的问题很清楚。代码中的其他所有内容都按预期工作。分享我认为相关但未按预期工作的 Redux 代码(如果这是正确的方法)。
我尝试在设置
serializableCheck: false
后将客户端对象存储在Redux中。但是客户端对象没有保存在 Redux 中,而是存储了一个空对象 ({})。我广泛使用 Redux,一切都工作正常,但我并不想在其他地方存储这样的对象。
这是 Redux 函数:
addConnectedMQTTClient: (state, action) => {
console.warn(action.payload.client); // This is showing the client as expected.
state.connected_mqtt_clients.push(action.payload.client);
redux状态显示:
"connected_mqtt_clients": [
{
"client": {}
}
]
一般来说,您应该在 Redux 存储中仅存储原语和普通对象。这就是可序列化中间件帮助确保您存储的任何内容都是 JSON 可序列化/反序列化的。但是,您可以禁用此中间件检查并在商店中存储更复杂的对象/类/等,就像您所做的那样。我怀疑这个
client
对象不适合通过 Redux 存储干净地持久化。
我提出了另一种存储数据的替代方案,该数据将用于构建/重建 Paho MQTT 客户端,例如
host
、port
、path
、clientId
等,用于创建新客户端。然后,您可以从商店中选择这些原语并根据需要重新创建客户端。
将
Client
参数保存到存储中:
addConnectedMQTTClient: (state, action) => {
state.connected_mqtt_clients.push(action.payload.clientArgs);
},
dispatch(addConnectedMQTTClient({
clientArgs: [host, port, path, clientId],
}));
从商店中选择
Client
参数并重新创建客户端:
在React组件中选择参数并构造:
const { clientArgs } = useSelector(state => state.connected_mqtt_clients[0].client);
const client = React.useMemo(() => {
return new Paho.Client(...clientArgs);
}, [clientArgs]);
创建一个构造客户端的记忆选择器函数:
import { createSelector } from '@reduxjs/toolkit';
export const selectClient = createSelector(
[state => state.connected_mqtt_clients[0].client],
client => {
return new Paho.Client(...client.clientArgs);
}
);
const client = useSelector(selectClient);
解决方案不仅仅限于上述,我确信还有其他方法可以实现这一点。