React的setState异步总结

看示例

下面这个点击示例,在点击的时候如果打印count的值,打印出来的不是更新后的count,而是更新前的count,比如当前点击的是1,点击后要变成2,但是count打印的时候只会打印1

js 复制代码
const Test = function () {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
    console.log(count, 'count');
  }, []);

  return <div onClick={handleClick}>click me {count}</div>;
};

打印的效果如下

setstate的用法

setState 是 React 中用于更新组件状态的方法之一。它可以接收新的状态值作为参数,并在状态更新后触发组件的重新渲染,从而更新视图。

在类组件中,setState 是通过 this.setState() 方法来调用的。这个方法可以接受两种参数:一个更新对象或者一个接收前一个状态和当前属性作为参数并返回新状态的函数。

1. 更新对象

js 复制代码
this.setState({ key: value });

这种方式用于更新状态中的一个或多个属性。当调用 setState 时,React 会将传入的对象与当前状态合并,然后触发组件重新渲染。这意味着你只需要传入要更新的属性,不需要传入整个状态对象。

2. 函数式更新

js 复制代码
    this.setState((prevState, props) => {
      return { key: prevState.key + 1 };
    });
    

为什么打印出的count为什么不是最新的

因为 React 的状态更新是异步的,用 setCount 更新状态时,React 并不会立即更新 count 的值。相反,它会将更新推迟到稍后的某个时间点。

这就是为什么每次点击后 console.log(count) 输出的值总是更新之前的值。因为在点击事件处理函数中,你直接使用了 count 的值,而在事件处理函数执行完毕后,React 才会将状态更新应用到组件上。

更新的情况

js 复制代码
const Test = function () {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, []);
    console.log(count, 'count');
  return <div onClick={handleClick}>click me {count}</div>;
};

如果把打印的函数放到外部,而不是函数的内部,那么每次更新都会是最新的值。

如何在更新的时候拿到最新的值

setState 是异步操作,不能立即在 setState 后访问更新后的状态,但如果在某些场景下,或者你的需求需要的情况下,想要在更新后立即拿到更新后的状态,并且在更新后执行某些操作,应该在 setState 的回调函数中进行。下面是一个示例:

js 复制代码
setOrderParams((prev) => ({
  ...prev,
  [type]: val,
}), () => {
  console.log('Updated orderParams:', orderParams);
});
js 复制代码
const Test = function () {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => ({
    setCount(prevCount => prevCount + 1);
  }),  () => {
  console.log('Updated orderParams:', orderParams);
});
  return <div onClick={handleClick}>click me {count}</div>;
};

总结

setState 是异步的,即状态更新不会立即生效。如果需要在状态更新后执行某些操作,可以将这些操作放在 setState 的回调函数中。

如果觉得有趣或有收获,请关注我的更新,给个喜欢和分享。您的支持是我写作的最大动力!

往期好文推荐

相关推荐
大怪v9 分钟前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
我是天龙_绍10 分钟前
vue3 props 如何写ts,进行类型标注
前端
叫我詹躲躲22 分钟前
n8n 自动化工作流平台完整部署
前端·langchain·领域驱动设计
追逐时光者1 小时前
.NET Fiddle:一个方便易用的在线.NET代码编辑工具
后端·.net
林树的编程频道2 小时前
快递的物流地图是怎么实现的
后端
洛小豆2 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
八怪2 小时前
联合索引使用高分区度字段的一个例子
后端
遂心_2 小时前
为什么 '1'.toString() 可以调用?深入理解 JavaScript 包装对象机制
前端·javascript
IT_陈寒2 小时前
JavaScript 性能优化:5 个被低估的 V8 引擎技巧让你的代码快 200%
前端·人工智能·后端
前端小张同学2 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端