【发布时间】:2022-01-07 06:14:50
【问题描述】:
我有一个使用 mqtt-react-hooks 和 redux 的简单反应应用程序。每次订阅者收到新消息时,我都想更新我的 redux 存储。
订阅者.tsx
import React, { useEffect} from 'react';
import { useSubscription } from 'mqtt-react-hooks';
import { useAppDispatch } from '../features/item/hooks';
import { addItem } from '../features/item/item-slice';
const Subscriber = () => {
const { message } = useSubscription('queue');
const dispatch = useAppDispatch();
useEffect(() => {
if (message && message.message) {
dispatch(addItem(JSON.parse(message.message)));
}
}, [message]);
return (
<span>{message}</span>
);
};
export default Subscriber
App.tsx
import React from 'react';
import './App.css';
import {useAppSelector} from './features/item/hooks'
import { Connector } from 'mqtt-react-hooks'
import Subscriber from './mqtt/Subscriber'
function App() {
const items = useAppSelector((state) => state.item.items);
return (
<>
<Connector brokerUrl="ws://localhost:9001"
options={{keepalive: 10}}>
<div className="item-holder">
{Array.from(items, ([key, it]) => ({ key, it })).map( (kvp) => { return <div>{kvp.it} key={kvp.key}></div>})}
</div>
<Subscriber />
</Connector>
</>
);
}
export default App;
如果我从订阅者中删除useEffect,消息就会被接收和更新。我可以发送任意数量的消息。但是,当我在useEffect 中调用dispatch(addItem(... 时,它会收到第一条消息,但会忽略所有以后的消息。我的蚊子经纪人说客户端已关闭连接。它从不尝试重新连接。
我对反应很陌生。我有一种感觉,我根本没有做这件事。我真正想要的是一个基于来自 mqtt 主题的消息来维护状态的 redux 存储。该应用程序具有允许用户将消息发布回 mqtt 代理并更改 redux 状态的按钮。
编辑
根据要求,这是 addItem 代码。
import {createSlice, PayloadAction} from '@reduxjs/toolkit'
interface ItemState {
items: Item[],
}
const initialState: ItemState = {
items: []
}
const orderSlice = createSlice({
name: 'items',
initialState,
reducers: {
addItem(state, action: PayloadAction<Item>) {
state.items.push(action.payload);
return state;
}
}
});
export const { addItem } = itemSlice.actions;
export default itemSlice.reducer;
而useAppDispatch来自./features/item/hooks
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import { RootState, AppDispatch } from './item-store'
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
但是,我要补充一点,我摆脱了这个并使用通常的 useDispatch 和 useSelector 而不是“useApp____”版本并得到了相同的结果。
我认为问题出在 mqtt-react-hooks 钩子上,但我的 react-fu 技能还不够高,无法解决。
【问题讨论】:
-
你能分享
addItem的代码和你的reducer代码吗? -
请同时分享提供
dispatch功能的useAppDispatch。尝试包含我们跟踪上述代码并查看/理解所有调用所需的所有相关代码。
标签: react-redux react-hooks mqtt redux-toolkit