美文网首页
React Hook 中 useState 异步回调获取不到最新

React Hook 中 useState 异步回调获取不到最新

作者: 泽赫 | 来源:发表于2021-07-16 10:46 被阅读0次

    异常代码

    import React, { useState, useEffect } from 'react';
    
    const App = () => {
      const [arr, setArr] = useState([0]);
    
      useEffect(() => {
        console.log(arr);
      }, [arr]);
    
      const handleClick = () => {
        Promise.resolve().then(() => {
          setArr([...arr, 1]); // 此时赋值前 arr 为:[0]
        })
          .then(() => {
            setArr([...arr, 2]); // 此时赋值前 arr 为旧状态仍然为:[0]
          });
      }
    
      return (
        <>
          <button onClick={handleClick}>change</button>
        </>
      );
    }
    
    export default App;
    

    上面代码,App 组件实际也是个闭包函数,handleClick 里面引用着 arr,第一次 setArr 后 arr 的值确实更新了,我们也可以在下面截图中看到,但此时 handleClick 事件处理函数作用域还是旧的,里面引用的 arr 仍然为旧的,导致第二次 setArr 后结果为 [0, 2]:

    解决方案一

    将上述代码使用第二种(回调)方式传参

    const handleClick = () => {
        Promise.resolve().then(() => {
          setArr(prevState => [...prevState, 1]); // 这里也可以不改,使用 setArr([...arr, 1]); 因为这里不需要获取最新状态
        })
          .then(() => {
            setArr(prevState => [...prevState, 2]); // 这里必须改成回调函数传参方式,否则会读取旧状态,导致异常
          });
      }
    

    解决方案二

    利用 ref

    import React, { useState, useRef, useEffect } from 'react';
    
    const App = () => {
      const [arr, setArr] = useState([0]);
      let ref = useRef();
      useEffect(() => {
        ref.current = arr;
        console.log(arr);
      });
    
      const handleClick = () => {
        Promise.resolve().then(() => {
          const now = [...ref.current, 1];
          ref.current = now;
          setArr(now);
        })
          .then(() => {
            setArr([...ref.current, 2]);
          });
      }
    
      return (
        <>
          <h1>{arr.toString()}</h1>
          <button onClick={handleClick}>change</button>
        </>
      );
    }
    
    export default App;
    

    官网中的一段话:如果你刻意地想要从某些异步回调中读取 最新的 state,你可以用 一个 ref 来保存它,修改它,并从中读取。

    相关文章

      网友评论

          本文标题:React Hook 中 useState 异步回调获取不到最新

          本文链接:https://www.haomeiwen.com/subject/xknvpltx.html