react useState数据更新不同步问题

本文探讨了在React应用中遇到的由于合并更新导致的数据延迟显示问题,并提供了四个解决方案:1) 使用`useRef`存储状态并在`useEffect`中更新;2) 直接用`useEffect`监听状态变化;3) 利用函数式更新 setState 以确保获取最新状态;4) 自定义`useCallbackState`钩子。这些方法有助于确保组件在状态变更时正确地呈现最新数据。
摘要由CSDN通过智能技术生成

原因

合并更新造成的数据不能及时更新(非标准异步过程)
为什么我会在我的函数中看到陈旧的 props 和 state ?

解决方案

1.使用useRef存值

在useEffect中监听state变化,存进ref中

import './App.css';
import React, { useState,useRef,useEffect} from 'react';

function App() {
    let [count,setCount]=useState(0)
    const myRef = useRef(null);
    const handleClick=(d)=>{
       setCount(count+3)
       console.log(myRef.current)
    }
    useEffect(() => {
        myRef.current=count+3
   }, [count])
  return (
    <div className="App">
      <header className="App-header">
            <p>{count}</p>
            <button onClick={handleClick}>+</button>
      </header>
    </div>
  );
}

export default App;

2.直接用useEffect监听变量
import './App.css';
import React, { useState,useRef,useEffect} from 'react';

function App() {
    let [count,setCount]=useState(0)
    const handleClick=(d)=>{
       setCount(count+3)
    }
    useEffect(() => {
       console.log(count)
   }, [count])
  return (
    <div className="App">
      <header className="App-header">
            <p>{count}</p>
            <button onClick={handleClick}>+</button>
      </header>
    </div>
  );
}

export default App;


3.回调函数传参

函数式更新
如果新的 state 需要通过使用先前的 state 计算得出,那么可以将函数传递给setState。该函数将接收先前的 state,并返回一个更新后的值。


function Example2() {
  const [number, setNumber] = useState(0);

  const lazy1 = () => {
    // 获取点击按钮时的 state
    setNumber(number + 1);
  };

  const lazy2 = () => {
    // 每次执行时都会再去获取新的 state,而不是使用点击触发时的 state
    setNumber(number => number + 1);
  };

  return (
    <div>
      <p>{number}</p>
      <button onClick={() => setNumber(number + 1)}>+</button>
      <br />
      <button onClick={lazy1}>lazy1:只能获取点击按钮时候的状态</button>
      <br />
      <button onClick={lazy2}>lazy2:每次执行都会重新获取state, 所以获取的都是最新的state</button>
    </div>
  );
}

export default Example2;

4.自定义hooks

export function useCallbackState(state) {
  const cbRef = useRef();
  const [data, setData] = useState(state);

  useEffect(() => {
    cbRef.current && cbRef.current(data);
  }, [data]);

  return [
    data,
    function(val, callback) {
      cbRef.current = callback;
      setData(val);
    },
  ];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值