Reactjs 更新React useEffect中的非状态变量
我有一个应用程序,它每秒通过WebSocket接收新数据。每秒钟我都会收到10到15条需要存储和显示的信息。当前,每次收到新数据时,我都会更新状态数组,但效果是每秒重新渲染屏幕10到15次 我想要实现的是将传入数据存储在一个数组中,但每秒只更新一次屏幕。 我无法使用的方法是创建一个非状态数组,在接收到新数据时更新该数组,并使用计时器每秒将该数据复制到状态数组 这是状态数组的声明:Reactjs 更新React useEffect中的非状态变量,reactjs,react-hooks,Reactjs,React Hooks,我有一个应用程序,它每秒通过WebSocket接收新数据。每秒钟我都会收到10到15条需要存储和显示的信息。当前,每次收到新数据时,我都会更新状态数组,但效果是每秒重新渲染屏幕10到15次 我想要实现的是将传入数据存储在一个数组中,但每秒只更新一次屏幕。 我无法使用的方法是创建一个非状态数组,在接收到新数据时更新该数组,并使用计时器每秒将该数据复制到状态数组 这是状态数组的声明: const [boatData2, _setBoatData2] = useState({}); c
const [boatData2, _setBoatData2] = useState({});
const boatDataRef = useRef(boatData2);
const setBoatData2 = (update) => {
boatDataRef.current = update;
_setBoatData2(update);
}
这是接收数据的钩子代码:
useEffect(() => {
if (!ws.current) return;
ws.current.onmessage = e => {
setDataFlowing(true);
setDataAge(0);
setScreenUpdates(screenUpdates => screenUpdates + 1);
//console.log('New Data');
const message = JSON.parse(e.data);
if (message.updates && message.updates.values) {
message.updates[0].values.forEach(obj => {
let newPath = obj.path.split('.').join("");
const update = {
path: obj.path,
value: obj.value,
timestamp: message.updates[0].timestamp,
valid: true,
age: 0,
};
now = Date.parse(message.updates[0].timestamp);
setBoatData2({ ...boatDataRef.current, [newPath]: update });
});
}
};
}, []);
这是每秒运行的代码:
useEffect(() => {
let interval = null;
if (isActive) {
interval = setInterval(() => {
setSeconds(seconds => seconds + 1);
let boatdata = boatData2;
//console.log(boatData3);
Object.values(boatdata).forEach(val => {
val.age = val.age + 1;
if (val.age > 30) {
val.valid = false;
}
});
setBoatData2(boatdata);
setDataAge(dataAge => dataAge + 1);
if (dataAge > 60) {
setDataFlowing(false);
}
}, 1000);
} else if (!isActive && seconds !== 0) {
clearInterval(interval);
}
return () => clearInterval(interval);
}, [isActive, seconds, boatData2]);
您可以在
useRef
的帮助下执行此操作
const messageRef = useRef([]);
这会在messageRef
中创建一个名为current
的对象,我们可以对其进行变异,而对其进行变异不会触发重新渲染。现在,您的messageRef
将如下所示
{
current: []
}
现在,无论何时从websocket获得消息,都将消息按如下所示推入此引用中
messageRef.current.push(your message)
现在,在函数中,它会在某个xyz秒后更新状态。可以使用此引用更新状态
setYourMessages(messageRef.current);
messageRef.current = []; // do this after you state update call. Else you will be pushing duplicate messages into the state