react前端useState异步更新数据的问题

文章讲述了在使用typescript和React时遇到useState异步更新状态的问题,以及三种解决方法:1)使用ref来保存和更新状态;2)通过回调函数传递参数确保获取最新状态;3)使用useEffect来处理副作用和二次赋值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先贴一个解决方法的原文链接:react useState 异步 数据获取不到 - 掘金

初学typescript,在React中遇到了useState异步更新的问题。

首先定了一个list,以及用来更新list的setMList函数

const [mList, setMList] = useState<number[]>([])

最开始我没有意识到异步的问题,直接使用setMList方法进行更新,并继续后续的逻辑。然后我发现mList并没有更新,最开始我只认为是删除指定元素的代码写错了,但debug后发现只是setMList“没有成功运行”。

//mList=[1,12,123,1234,123456....]
setMList(produce(mList, draft => {
    const index = draft.findIndex(c => c === 123456);
    if (index !== -1) {
        draft.splice(index, 1);
    }
}))
console.log(mList)
//mList=[1,12,123,1234,123456....]

这主要是因为useState在React中是异步更新的问题,用同步的写法只能靠撞大运。作为初学者,我选择使用一个中间变量的方式,让console.log变得同步。参考转载文章的方法三。

方法一 : 利用 ref

  • 官网中的一段话:如果你刻意地想要从某些异步回调中读取最新的 state,你可以用 一个 ref 来保存它,修改它,并从中读取
  • 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 (
          <button onClick={handleClick}>change</button>
      );
    }
    

方法二 :使用(回调)方式传参

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

3.png

方法三 : 处理办法添加一个 副作用(useEffect()

  • 异步获取数据存在的问题, 我这里通过useEffect用存储2次, 没办法 ,解决问题就行了,其他的也不重要
  • const [categtry, setCategtry] = useState([]);
    const [categData, setCategData] = useState([]);
     
    useEffect(() => {
        getCollaCategory();
      }, []);
     
    useEffect(() => {
    // 这个useEffect很关键,第一次赋值但是获取不到,所以要再赋值一次
       if (categtry) {
         setCategData(categtry);
       }
    }, [categtry]);
     
    const getCollaCategory = async () => {
       const { resp } = await call(service.getCollaCategory);
       if (resp.Code === 0) {
        // 第一次虽然在这里赋值了,但是外部想拿到 categtry这个变量还是空的
          setCategtry(resp.CategoryTree.SubCategoryList);
       }
    }
    

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值