首页 > 其他分享 >前端React篇之React setState 调用的原理、React setState 调用之后发生了什么?是同步还是异步?

前端React篇之React setState 调用的原理、React setState 调用之后发生了什么?是同步还是异步?

时间:2024-03-16 17:59:39浏览次数:27  
标签:状态 调用 更新 React 组件 setState

目录


React setState 调用的原理

在React中,setState方法是用于更新组件状态的重要方法。当setState被调用时,React会对组件进行重新渲染,以反映状态的变化。

具体的执行过程如下:

  1. 调用setState入口函数:当你在组件中调用setState方法时,实际上是调用了React组件的setState方法。这个方法在内部充当一个分发器的角色,根据传入的参数,将其分发到不同的功能函数中去。
ReactComponent.prototype.setState = function (partialState, callback) {
  this.updater.enqueueSetState(this, partialState);
  if (callback) {
    this.updater.enqueueCallback(this, callback, 'setState');
  }
};
  1. 将新的state放入状态队列enqueueSetState方法将新的state放进组件的状态队列里,并调用enqueueUpdate来处理将要更新的实例对象。
enqueueSetState: function (publicInstance, partialState) {
  // 根据 this 拿到对应的组件实例
  var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');
  // 这个 queue 对应的就是一个组件实例的 state 数组
  var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);
  queue.push(partialState);
  //  enqueueUpdate 用来处理当前的组件实例
  enqueueUpdate(internalInstance);
}
  1. 处理更新:在enqueueUpdate方法中,React会检查当前是否正在进行批量更新。如果是,那么组件会被添加到dirtyComponents队列中,等待下一次的批量更新。如果不是,那么React会立即开始批量更新。
function enqueueUpdate(component) {
  ensureInjected();
  // 注意这一句是问题的关键,isBatchingUpdates标识着当前是否处于批量创建/更新组件的阶段
  if (!batchingStrategy.isBatchingUpdates) {
    // 若当前没有处于批量创建/更新组件的阶段,则立即更新组件
    batchingStrategy.batchedUpdates(enqueueUpdate, component);
    return;
  }
  // 否则,先把组件塞入 dirtyComponents 队列里,让它“再等等”
  dirtyComponents.push(component);
  if (component._updateBatchNumber == null) {
    component._updateBatchNumber = updateBatchNumber + 1;
  }
}
  1. 批处理更新:React会对setState的调用进行批处理,以提高性能。这意味着React会延迟实际的状态更新,并且在合适的时机进行批量更新,从而避免不必要的重复渲染。

  2. 触发重新渲染:最后,React会触发组件的重新渲染,以反映状态的变化。这个过程包括调用render方法来创建新的虚拟DOM,然后使用新的虚拟DOM和旧的虚拟DOM进行对比,最后更新实际的DOM。

总之,setState方法通过触发组件重新渲染来更新状态,它使用批处理和异步更新来优化性能,并且可以接受回调函数用于在状态更新完成后执行额外的操作。

React setState 调用之后发生了什么?是同步还是异步?

在React中,setState方法是用于更新组件状态的重要方法。当setState被调用时,React会将新的状态放入组件的状态队列中,并在适当的时机进行批处理更新,以提高性能。最后,React会触发组件的重新渲染,以反映状态的变化。这个过程是异步的,因为React会对多个setState调用进行批处理,并且延迟实际的状态更新。这种机制有助于提高性能,避免不必要的重复渲染,并且确保在适当的时机进行状态更新和重新渲染。

React setState 调用之后发生了什么?

在React中,setState方法的调用会触发一系列的操作,以更新组件的状态和重新渲染。这个过程可以概括如下:

  1. 状态更新:当setState被调用时,React会将新的状态合并到组件的状态中。

  2. 触发重新渲染:状态更新后,React会触发组件的重新渲染。React会比较新旧虚拟DOM树的差异,并且只更新必要的部分,以最小化DOM操作。

  3. 生命周期方法调用:在重新渲染之前和之后,相关的生命周期方法(如shouldComponentUpdatecomponentWillUpdatecomponentDidUpdate)会被调用。

  4. 异步更新setState的更新是异步的。多个setState调用可能会被合并成单个更新,以提高性能并减少不必要的重复渲染。

  5. 回调函数执行:如果setState调用时传递了回调函数,该回调函数会在状态更新完成并且组件重新渲染后被调用。

总体来说,setState调用是异步的,因为React会对多个setState调用进行批处理,并且延迟实际的状态更新。这种机制有助于提高性能,避免不必要的重复渲染,并且确保在适当的时机进行状态更新和重新渲染。

setState 是同步还是异步的

在React中,setState的更新是异步的。这意味着,当你调用setState时,React并不会立即更新组件的状态,而是将新的状态放入一个队列中,然后在适当的时机进行批处理更新。

这种异步更新的机制有助于提高性能,因为React可以将多个setState调用合并成单个更新,从而减少不必要的重复渲染。然而,这也意味着你不能立即在setState后获取更新后的状态,因为setState的更新可能还没有被应用。

如果你需要在setState后立即获取更新后的状态,你可以在setState的第二个参数中传递一个回调函数。这个回调函数会在状态更新完成并且组件重新渲染后被调用,这时你可以获取到最新的状态。

总的来说,setState的更新是异步的,但你可以通过回调函数来获取更新后的状态。

持续学习总结记录中,回顾一下上面的内容:
React中的setState方法是用于更新组件状态的重要方法。当setState被调用时,React会将新的状态放入组件的状态队列中,并在适当的时机进行批处理更新,以提高性能。最后,React会触发组件的重新渲染,以反映状态的变化。这个过程是异步的,因此连续调用setState不会立即引起多次重新渲染,而是将它们合并成一次更新操作。
在React中,setState的调用会触发一系列的操作。首先,React会将新的状态合并到组件的状态中。然后,React会触发组件的重新渲染,比较新旧虚拟DOM树的差异,并更新必要的部分。在重新渲染之前和之后,相关的生命周期方法会被调用。setState的更新是异步的,因此多个setState调用可能会被合并成单个更新,以提高性能。如果setState调用时传递了回调函数,该回调函数会在状态更新完成并且组件重新渲染后被调用。在React中,setState的更新是异步的。这意味着,当你调用setState时,React并不会立即更新组件的状态,而是将新的状态放入一个队列中,然后在适当的时机进行批处理更新。这种异步更新的机制有助于提高性能,因为React可以将多个setState调用合并成单个更新,从而减少不必要的重复渲染。

标签:状态,调用,更新,React,组件,setState
From: https://blog.csdn.net/qq_37255976/article/details/136689593

相关文章

  • python调用c语言API
    python调用C语言API,一般使用内置的ctypes库.但是这个库用起来不那么方便,主要是需要进行函数和数据结构的包装.如下所示:#结构定义classCOORD(Structure):"""COORDstructure"""_fields_=[("X",SHORT),("Y",SHORT)]#函数定义UpdateP......
  • C++函数调用优化
    C++函数调用优化施磊老师网课笔记截图1、用临时对象拷贝构造一个新对象的时候,编译器会对其优化,直接用生成临时对象的方法构造新对象;......
  • React — Class类组件
    一、Class类组件基础模板import'./App.css';import{Component}from'react'classCounterextendsComponent{//编写组件的逻辑代码//1.状态变量事件回调UI//2.定义状态变量state={count:0}setCount=()=>{this.setState({c......
  • matlab调用python
    一、matlab命令行窗口检查python状态 我这里显示没有配置,然后添加python路径 由于我的python是最近安装的,出现了版本兼容问题,可以参考:VersionsofPythonCompatiblewithMATLABProductsbyRelease-MATLAB&Simulink(mathworks.cn) 具体的配置方法参考官方提供......
  • iOS端创建ReactNative容器第一步:打出jsbundle和资源包
    react-native的打包流程是通过执行react-nativebundle指令进行的。 添加构建指令修改RN项目中的package.json文件,先其中添加构建命令build-release-ios和build-debug-ios"scripts":{"android":"react-nativerun-android","ios":"react-nativerun-ios"......
  • React-hook-form-mui(二):表单数据处理
    前言在上一篇文章中,我们介绍了react-hook-form-mui的基础用法。本文将着表单数据处理。react-hook-form-mui提供了丰富的表单数据处理功能,可以通过watch属性来获取表单数据。Demo下面是一个使用watch属性的例子:importReactfrom'react';import{useForm}from're......
  • React — forwardRef
    React.forwardRef是React提供的一个API,用于在函数组件中向子组件传递ref。通过使用React.forwardRef,我们可以将ref传递给函数组件内部的DOM节点或其他组件,从而实现对其进行操作。import{forwardRef}from"react"constSon=forwardRef((prop,ref)=>{return......
  • 使用 React Router 的 withRouter
    使用ReactRouter的withRouterReactRouter是React应用中常用的路由管理工具,它可以帮助我们管理页面之间的导航和状态。而withRouter则是ReactRouter提供的一个高阶组件,用于将路由相关的属性注入到组件中,使得我们可以在不同的组件中访问路由信息。1.安装Reac......
  • React — useReducer使用方法
    1.定义一个reducer函数(根据不同的action返回不同的新状态)2.在组件中调用useReducer,并传入reducer函数和状态的初始值3.事件发生时,通过dispatch函数分发一个action对象(通知reducer)要返回哪个新状态并渲染UIimport{useReducer}from"react"//1.定义一个reducer函数,根据不......
  • vue3 中ref和reactive的区别讲解
    1.定于数据角度对比:ref用来定义:基本类型数据reactive用来定义:对象、或数组类型的数据备注:ref也可以用来定义对象或数组类型数据,它内部会自动通过reactive转为代理对象2.原理角度对比:ref通过Object.defineProperty()的get与set来实现响应式的(数据劫持)reactive通过......