IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React State 原理理解 -> 正文阅读

[JavaScript知识库]React State 原理理解

问题:setState 到底是同步还是异步的?

如果对 React 底层有一定了解,可以回答出 batchUpdate 批量更新概念,以及批量更新被打破的条件。

答案:有时是同步,有时是异步。

  • 在 合成事件 和 生命周期函数 里是 异步
  • 在 原生事件 和 setTimeout、promise里是 同步

造成setState的异步并不是由内部的异步代码引起的,在本身的执行过程中时同步的,但是合成事件和生命周期函数的调用顺序在更新之前,导致在内部不能直接得到更新后的值,可以用第二个参数 callback 来获取。

具体解释:可参考setState的执行过程


类组件state

setState(obj,callback)

  • 第一个参数:当 obj 为一个对象,则为即将合并的 state ;如果 obj 是一个函数,那么当前组件的 state 和 props 将作为参数,返回值用于合并新的 state。
  • 第二个参数 callback :callback 为一个函数,函数执行上下文中可以获取当前 setState 更新后的最新 state 的值,可以作为依赖 state 变化的副作用函数,可以用来做一些基于 DOM 的操作。

一次事件中触发一次如上 setState ,在 React 底层执行过程:

render 阶段 render 函数执行 -> commit 阶段真实 DOM 替换 -> setState 回调函数执行 callback

在这里插入图片描述

  • 首先,setState 会产生当前更新的优先级(老版本用 expirationTime ,新版本用 lane )。
  • 接下来 React 会从 fiber Root 根部 fiber 向下调和子节点,调和阶段将对比发生更新的地方,更新对比 expirationTime ,找到发生更新的组件,合并 state,然后触发 render 函数,得到新的 UI 视图层,完成 render 阶段
  • 接下来到 commit 阶段,commit 阶段,替换真实 DOM ,完成此次更新流程。
  • 此时仍然在 commit 阶段,会执行 setState 中 callback 函数,到此为止完成了一次 setState 全过程。

setState原理揭秘

本质:React 底层调用 Updater 对象上的 enqueueSetState 方法

enqueueSetState():创建一个update,放入当前 fiber对象 的待更新队列中,最后开启调度更新,进入更新流程。

在这里插入图片描述

React 的 batchUpdate 批量更新

目的:多次 setstate 会让逻辑多停留在 js 运行层面,阻塞了浏览器绘制,因此需要批量更新

batchedEventUpdates ():

在这里插入图片描述

分析流程:

  • React 事件执行前通过 isBatchingEventUpdates=true 打开开关,开启事件批量更新
  • 当事件结束,通过 isBatchingEventUpdates=false 关闭开关
  • scheduleUpdateOnFiber 中根据这个开关来确定是否进行批量更新

1)异步环境下,继续开启批量更新模式:

异步操作里面的批量更新规则会被打破,因此提供了手动批量更新方法: unstable_batchedUpdates

2)提升更新优先级:

提供了方法: flushSync,可以将回调函数中的更新任务,放在一个较高的优先级中优先执行

补充:flushSync 在同步条件下,会合并之前的 setState | useState

3)总结:React 同一级别更新优先级 关系是:

flushSync 中的 setState > 正常执行上下文中 setState > 异步 setTimeout ,Promise 中的 setState


函数组件state

const [ state , dispatch ] = useState(initData)

  • ① state 目的提供给 UI ,作为渲染视图的数据源
  • ② dispatch 改变 state 的函数,可以理解为推动函数组件渲染的渲染函数
  • ③ initData 初始值

initData的初始值

  • 第一种情况是非函数,将作为 state 初始化的值
  • 第二种情况是函数,函数的返回值作为 useState 初始化的值

dispatch的参数

  • 第一种非函数情况,此时将作为新的值,赋予给 state,作为下一次渲染使用
  • 第二种是函数的情况,如果 dispatch 的参数为一个函数,这里可以称它为reducer,reducer 参数,是上一次返回最新的 state,返回值作为新的 state

监听 state 变化

useEffect :常可以把 state 作为 依赖项 传入 useEffect 第二个参数 deps ,但是注意 useEffect 初始化会默认执行一次

dispatch更新特点

与类组件一样,但是当调用改变 state 的函数dispatch,在本次函数执行上下文中,是获取不到最新的 state 值的

在这里插入图片描述
原因:函数组件更新就是函数的执行,在一次执行过程中,函数内部所有变量重新声明,所以改变的 state 只有在下一次函数执行时才更新。

useState 原理在之后 Hooks 讲解


问:类组件中的 setState 和函数组件中的 useState 有什么异同?

答:相同点:

  • 原理:setState 和 useState 更新视图,底层都调用了 scheduleUpdateOnFiber 方法,而且事件驱动情况下都有批量更新规则
  • 语法:第一个参数都可以传入函数

不同点:

  • 在不是 pureComponent 组件模式下, setState 不会浅比较两次 state 的值。只要调用 setState 就会执行更新。但是 useState 中 dispatchAction 会默认比较两次state是否相同来更新组件
  • setState 有专门监听 state 变化的回调函数 callback,可以获取最新 state。但是 useState 只能通过 useEffect 来执行 state 变化引起的副作用
  • setState 在底层处理逻辑时将旧 state 进行合并处理,而 useState 是重新赋值
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-14 01:52:39  更:2022-01-14 01:54:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:28:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码