使用 React 钩子和 MQTT 处理对象列表



我正在尝试使用钩子处理 React 中的对象列表。对象的更新是使用 MQTT 接收的。

我首先尝试使用一个名为mqtt-react-hooks的库(最近从Github中消失了(。该库提供了一个useSubscription函数,该函数返回在订阅主题上收到的最新消息。

基本上我的组件看起来像这样,我的对象是节点:

function MQTTApp(props) {
const [nodes, setNodes] = useState([]);
const { lastMessageOnTopic } = useSubscription('node/#');
...
}

这种方法的问题在于,每次收到消息时都会呈现我的组件。当收到 MQTT 消息时,需要对其进行解析,并且并不总是导致节点更新。我想要的是,我的组件仅在节点列表有效更改时才呈现。

所以我尝试转储mqtt-react-hooks库并编写自己的代码。在它下面也使用 MQTT.js。它基于本文。

我的代码现在看起来像这样:

function MQTTApp(props) {
const [nodes, setNodes] = useState([]);
function handleMessage(m) {
...
setNodes([...nodes, newNode]);
}
useEffect(() => {
const client = mqttService.getClient();
mqttService.onMessage(client, handleMessage);
mqttService.subscribe(client, 'node/#');
return () => mqttService.closeConnection(client);
}, []);
...
}

这个想法是组件创建一个 MQTT 客户端并在挂载时订阅主题。我在这里遇到的问题是回调总是引用节点的初始列表(为空(。由于我将节点列表视为不可变,因此在调用setNodes时总是创建一个副本,因此nodes引用更改。所以最后,当收到更新时,我会继续丢失以前的节点。

我想不出一种干净简单的方法来解决这个问题。有人有想法吗?

谢谢

您的useEffect执行一次。附加到onMessage侦听器的函数引用handleMessagenodes始终使用节点的初始值(由于闭包(。

因此,请使用回调方法来设置状态。

function MQTTApp(props) {
const [nodes, setNodes] = useState([]);
function handleMessage(m) {
...
setNodes(prev => [...prev, newNode]); <-------- see here
}
useEffect(() => {
const client = mqttService.getClient();
mqttService.onMessage(client, handleMessage);
mqttService.subscribe(client, 'node/#');
return () => mqttService.closeConnection(client);
}, []);
...
}

相关内容

  • 没有找到相关文章

最新更新