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

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

往期好文推荐

相关推荐
源代码•宸5 分钟前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
C澒12 分钟前
前端整洁架构(Clean Architecture)实战解析:从理论到 Todo 项目落地
前端·架构·系统架构·前端框架
C澒19 分钟前
Remesh 框架详解:基于 CQRS 的前端领域驱动设计方案
前端·架构·前端框架·状态模式
Charlie_lll22 分钟前
学习Three.js–雪花
前端·three.js
onebyte8bits39 分钟前
前端国际化(i18n)体系设计与工程化落地
前端·国际化·i18n·工程化
晚霞的不甘43 分钟前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
马猴烧酒.43 分钟前
【面试八股|JVM虚拟机】JVM虚拟机常考面试题详解
jvm·面试·职场和发展
C澒1 小时前
前端分层架构实战:DDD 与 Clean Architecture 在大型业务系统中的落地路径与项目实践
前端·架构·系统架构·前端框架
BestSongC1 小时前
行人摔倒检测系统 - 前端文档(1)
前端·人工智能·目标检测
喵叔哟1 小时前
06-ASPNETCore-WebAPI开发
服务器·后端·c#