我在React中有一个长数组,超过600个字符串项。我有一个map函数,它在日志中列出这些字符串。当我更新空列表以添加所有字符串时,更新是相当即时的,但HTML本身需要永远更新/根本不更新。只有当我更改代码并触发某种快速重载时,HTML才会更新,除此之外,它没有响应。
我最初的怀疑是因为列表太长,所以列表没有呈现,但是在用只有2到3个项目的测试列表尝试之后,它仍然不起作用。现在我认为这是由于我通过WebSocket获取列表中的项目。
const [logs, pushLogs] = useReducer(
(prev, next) => {
prev.push(...next);
return prev;
},
["Initializing..."]
);
useSWRSubscription(
`ws://${host}/api/users/logs?id=${props.id}`,
(key, { next }) => {
const socket = new WebSocket(key);
socket.addEventListener("message", ({ data }) => {
pushLogs(data.split("\n"));
if (data.includes("Finished")) {
return () => socket.close();
}
return next(null, data);
});
socket.addEventListener("error", (event) => next(event.error));
return () => socket.close();
}
);
我使用SWR来获取日志,reducer钩子只是一个状态数组,我可以更容易地将其推到。SWR是NextJS(我的堆栈)推荐的获取东西的方式,但在大多数情况下,它只是一个普通的WebSocket。我像这样Maplogs
数组。
{logs.map((log, index) => {
return (
<span
key={index}
>
{log}
</span>
);
})}
如何使用WebSocket立即更新我的阵列?
1条答案
按热度按时间nzrxty8p1#
你的问题是你正在使用push来改变Array。由于Array仍然是相同的对象,React不知道它已经改变了。React通过引用而不是值进行比较。
从React文档中,以下是如何以React可以看到的方式添加到Array中:
push()将改变一个数组,这是你不希望看到的。
相反,创建一个新数组,其中包含现有项和末尾的新项。有多种方法可以做到这一点,但最简单的方法是使用...数组扩展语法