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 的回调函数中。

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

往期好文推荐

相关推荐
王家视频教程图书馆1 分钟前
rust 写gui 程序 最流行的是哪个
开发语言·后端·rust
Hello--_--World5 分钟前
VUE:逻辑复用
前端·javascript·vue.js
好大哥呀10 分钟前
如何在Spring Boot中配置数据库连接?
数据库·spring boot·后端
老神在在00118 分钟前
企业级 SpringBoot 后端通用开发规范|统一响应 + 敏感字段加密
spring boot·后端·状态模式
zjeweler19 分钟前
网安护网面试-1-长亭护网面试
web安全·网络安全·面试·职场和发展
陶甜也22 分钟前
3D智慧城市:blender建模、骨骼、动画、VUE、threeJs引入渲染,飞行视角,涟漪、人物行走
前端·3d·vue·blender·threejs·模型
csdn_aspnet26 分钟前
在 ASP.NET Core (WebAPI) 中启用 CORS
后端·asp.net·.netcore
好家伙VCC26 分钟前
**InfluxDB实战进阶:基于Golang的高性能时序数据采集与可视化方
java·开发语言·后端·python·golang
患得患失94927 分钟前
【前端websocket】企业级功能清单
前端·websocket·网络协议
落魄江湖行27 分钟前
基础篇四 Nuxt4 全局样式与 CSS 模块
前端·css·typescript·nuxt4