使用mqtt-react-hooks的Subscriber接收一条消息后停止工作如何解决
根因定位
- 核心问题:MQTT连接容器
<Connector>被放在了订阅了Reduxitems状态的App组件内部。每次调用dispatch(addItem)后,items更新触发App重渲染,<Connector>会被卸载再重新挂载,原有MQTT连接直接被销毁,就会出现仅能接收第一条消息后连接断开的问题。 - 次要问题:Redux Toolkit Slice的reducer写法错误,你既直接修改了draft state,又显式返回了state,不符合Immer的使用规范,可能引发状态异常。
- 代码笔误:列表渲染时
key属性写错了位置,Slice变量名前后不统一(orderSlice和itemSlice混用)。
解决方案
第一步:调整挂载位置
将<Connector>移动到不会因MQTT消息更新触发重渲染的外层组件,通常直接放在项目入口文件(index.js/main.tsx)即可:
// 入口文件示例 import React from 'react' import ReactDOM from 'react-dom/client' import { Provider } from 'react-redux' import { Connector } from 'mqtt-react-hooks' import store from './features/item/item-store' import App from './App' ReactDOM.createRoot(document.getElementById('root')).render( <Provider store={store}> <Connector brokerUrl="ws://localhost:9001" options={{keepalive: 10}}> <App /> </Connector> </Provider> )
修改后移除App.tsx里的<Connector>标签,避免重复嵌套。
第二步:修正Slice的错误写法
统一Slice变量名,删除reducer里多余的return state:
import {createSlice, PayloadAction} from '@reduxjs/toolkit' interface ItemState { items: Item[], } const initialState: ItemState = { items: [] } // 统一变量名为itemSlice const itemSlice = createSlice({ name: 'items', initialState, reducers: { addItem(state, action: PayloadAction<Item>) { state.items.push(action.payload); // 删除多余的return语句 } } }); export const { addItem } = itemSlice.actions; export default itemSlice.reducer;
第三步:修正列表渲染语法错误
调整App.tsx中列表渲染的key属性位置:
<div className="item-holder"> {Array.from(items, ([key, it]) => ({ key, it })).map(kvp => <div key={kvp.key}>{kvp.it}</div> )} </div>
做完以上修改后,MQTT连接不会随Redux状态更新断开,就可以持续接收消息更新Redux存储了。
内容的提问来源于stack exchange,提问作者toshiomagic
相关产品推荐
相关产品推荐

