参见演示here
我正在连接到套接字(由setTimeouts建模!)并获得一个数组。在安装时,我得到一个初始阵列。然后,我继续监听该阵列的更新。更新仅作为更改而不是整个数组发送。
我需要访问当前状态,但是它是空的。即使在渲染中看起来不错。
我认为这可能是由于numbers
在调用addLater()
时为空而导致的范围限定或关闭错误,但是我不确定解决方案是什么。
import React, { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const [numbers, setNumbers] = useState([]);
useEffect(() => {
// initial connection to socket
setNumbers(["first", "second", "third"]);
// incoming messages from socket
addLater();
addMuchLater();
}, []);
const addLater = () => {
window.setTimeout(() => {
console.log("Why is the state empty? ", numbers);
const changedNumbers = [...numbers];
changedNumbers.splice(1, 1, "fourth");
setNumbers(changedNumbers);
}, 5000);
};
const addMuchLater = () => {
window.setTimeout(() => {
const changedNumbers = [...numbers];
changedNumbers.splice(2, 1, "fifth");
setNumbers(changedNumbers);
}, 10000);
};
return (
<div className="App">
{numbers.map((r, i) => (
<p>
{i}: {r}
</p>
))}
</div>
);
}
答案 0 :(得分:1)
当下一个值取决于上一个值时,最好将代码编写为functional update,这样代码将始终作用于最新值。遇到问题时,当前代码将关闭numbers
的原始值,这不是您想要的:
const addLater = () => {
window.setTimeout(() => {
setNumbers(prevNumbers => {
const changedNumbers = [...prevNumbers];
changedNumbers.splice(1, 1, "fourth");
return changedNumbers;
});
}, 5000);
};
const addMuchLater = () => {
window.setTimeout(() => {
setNumbers(prevNumbers => {
const changedNumbers = [...prevNumbers];
changedNumbers.splice(2, 1, "fifth");
return changedNumbers;
});
}, 10000);
};
答案 1 :(得分:0)
setState是异步的,因此稍后在函数中发生的状态调用将获得呈现组件时的状态,而不是设置新状态后的状态。您可以将回调函数用作第二个参数:
useEffect(() => {
// initial connection to socket
setNumbers(["first", "second", "third"],
()=>{
// incoming messages from socket
addLater();
addMuchLater();
}), []);
请参阅: https://upmostly.com/tutorials/how-to-use-the-setstate-callback-in-react