简体   繁体   English

如何在 React 的 while 循环内更新 State

[英]How do I update State inside of a while loop in React

Say I have this code.说我有这个代码。

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} at the end of the functionanl component.我在函数组件的末尾返回 {arr.length} 。 However, it first renders 10, and waits till the whole while loop is run and then renders 1. All the numbers inbettween are simply skipped.但是,它首先呈现 10,并等待整个 while 循环运行,然后呈现 1。中间的所有数字都被简单地跳过。

I kind of understand why this happens, but is there anyway I can show all the lengths?我有点理解为什么会发生这种情况,但是无论如何我可以展示所有的长度吗? I have a sleep function that takes milliseconds and halts the program for that time, if it is of any use in order to make sure the user can see the rendered lengths for a reasonable time.我有一个睡眠 function 需要几毫秒并在这段时间内暂停程序,如果它有任何用处,以确保用户可以在合理的时间内看到渲染的长度。

Thanks in advance!提前致谢!

Assuming this is a functional component (I'm guessing you meant useState , not setState , in const[arr,setArr]=setState(s); ), you need to let the component render each state before setting the next.假设这是一个功能组件(我猜你的意思是useState ,而不是setState ,在const[arr,setArr]=setState(s); ),你需要让组件在设置下一个之前渲染每个 state 。 Otherwise, all the state updates get batched together and the component only renders again when they're all done.否则,所有 state 更新都会一起批处理,并且组件只有在全部完成后才会再次呈现。

For instance:例如:

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>;
}

I think you can use useEffect hook我认为你可以使用useEffect钩子

Each time, we change arr , hook will be called with some timeout每次,我们改变arr ,钩子都会被调用并有一些超时

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]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM