You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mqtt-react-hooks的Subscriber接收一条消息后停止工作如何解决

根因定位

  1. 核心问题:MQTT连接容器<Connector>被放在了订阅了Redux items状态的App组件内部。每次调用dispatch(addItem)后,items更新触发App重渲染,<Connector>会被卸载再重新挂载,原有MQTT连接直接被销毁,就会出现仅能接收第一条消息后连接断开的问题。
  2. 次要问题:Redux Toolkit Slice的reducer写法错误,你既直接修改了draft state,又显式返回了state,不符合Immer的使用规范,可能引发状态异常。
  3. 代码笔误:列表渲染时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:45:04