如何在 React 的 while 循环中更新状态
How do I update State inside of a while loop in React
说我有这个代码。
var s = [1,2,3,4,5,6,7,8,9,0];
const[arr,setArr]=useState(s);
while(arr.length != 0){
setArr(arr.splice(0,1));
console.log(arr); //This returns [2,3,4,5,6,7,8,9,0] and [3,4,5,6,7,8,9,0] and so on until []
}
I return {arr.length} 在函数组件的末尾。但是,它首先渲染 10,等到整个 while 循环 运行 然后渲染 1。所有 inbettween 的数字都被简单地跳过。
我有点理解为什么会这样,但是无论如何我可以显示所有长度吗?我有一个睡眠功能,它需要几毫秒并在这段时间内暂停程序,如果它有任何用处,以确保用户可以在合理的时间内看到渲染的长度。
提前致谢!
假设这是一个功能组件(我猜你的意思是useState
,而不是setState
,在const[arr,setArr]=setState(s);
),你需要让组件在设置之前渲染每个状态下一个。否则,所有状态更新都会一起批处理,并且组件只会在它们全部完成后再次呈现。
例如:
function Example() {
const [arr, setArr] = useState([1,2,3,4,5,6,7,8,9,0]);
// Set up a timer on mount, remove it on dismount and when
// we run out of values to show
useEffect(() => {
const handle = setInterval(() => {
// Note useing the callback function, so `arr` isn't stale
// in this callback
setArr(a => {
if (a.length) {
// Update the array, dropping the first entry
return a.slice(1);
}
// No more entries, stop the timer
clearInterval(handle);
return a;
});
}, 500);
return () => clearInterval(handle);
}, []);
return <div>{arr.join()}</div>;
}
我认为你可以使用 useEffect
钩子
每次,我们改变arr
,hook 会在超时后被调用
const SHOW_TIMEOUT = 300;
var s = [1,2,3,4,5,6,7,8,9,0];
const [arr, setArr] = useState(s);
useEffect(() => {
const timeoutId = setTimeout(() => setArr(arr.slice(1)), SHOW_TIMEOUT);
return () => clearTimeout(timeoutId); // also need to stop timeout in case of unmount
}, [arr]);
说我有这个代码。
var s = [1,2,3,4,5,6,7,8,9,0];
const[arr,setArr]=useState(s);
while(arr.length != 0){
setArr(arr.splice(0,1));
console.log(arr); //This returns [2,3,4,5,6,7,8,9,0] and [3,4,5,6,7,8,9,0] and so on until []
}
I return {arr.length} 在函数组件的末尾。但是,它首先渲染 10,等到整个 while 循环 运行 然后渲染 1。所有 inbettween 的数字都被简单地跳过。
我有点理解为什么会这样,但是无论如何我可以显示所有长度吗?我有一个睡眠功能,它需要几毫秒并在这段时间内暂停程序,如果它有任何用处,以确保用户可以在合理的时间内看到渲染的长度。
提前致谢!
假设这是一个功能组件(我猜你的意思是useState
,而不是setState
,在const[arr,setArr]=setState(s);
),你需要让组件在设置之前渲染每个状态下一个。否则,所有状态更新都会一起批处理,并且组件只会在它们全部完成后再次呈现。
例如:
function Example() {
const [arr, setArr] = useState([1,2,3,4,5,6,7,8,9,0]);
// Set up a timer on mount, remove it on dismount and when
// we run out of values to show
useEffect(() => {
const handle = setInterval(() => {
// Note useing the callback function, so `arr` isn't stale
// in this callback
setArr(a => {
if (a.length) {
// Update the array, dropping the first entry
return a.slice(1);
}
// No more entries, stop the timer
clearInterval(handle);
return a;
});
}, 500);
return () => clearInterval(handle);
}, []);
return <div>{arr.join()}</div>;
}
我认为你可以使用 useEffect
钩子
每次,我们改变arr
,hook 会在超时后被调用
const SHOW_TIMEOUT = 300;
var s = [1,2,3,4,5,6,7,8,9,0];
const [arr, setArr] = useState(s);
useEffect(() => {
const timeoutId = setTimeout(() => setArr(arr.slice(1)), SHOW_TIMEOUT);
return () => clearTimeout(timeoutId); // also need to stop timeout in case of unmount
}, [arr]);