仲灏小栈 仲灏小栈
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

仲灏

诚意, 正心, 格物, 致知
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《前端项目基础建设》
  • HTML&CSS

  • JavaScript&TypeScript

  • Node

  • 构建

  • Vue

  • React

    • Vue 放弃繁琐的render函数,拥抱JSX
    • Awesome React
    • React 文档(vue版)
    • react 项目开发注意事项
    • 常见功能实现
    • react 常见坑集合
    • ant design pro 学习
    • ProComponents设计思路
    • 万条数据渲染优化
    • react hook 与 闭包
    • JSX
    • React生命周期
    • React 基本使用 setState
    • React 基本使用 组件生命周期
    • React 高级使用 性能优化
    • React 高级使用 高阶组件
    • React Redux使用
    • react-router 使用
    • React 原理
      • vdom 和 diff 算法
      • JSX 本质
      • 合成事件
        • 为何要合成事件机制?
        • React 17 事件绑定到 root
      • setState 和 batchUpdate
        • 核心要点
        • setState 主流程
        • batchUpdate 机制
        • transaction 事务机制
      • 组件渲染过程
        • 组件更新过程
        • 更新的两个阶段
      • fiber 性能
        • 可能会有性能问题
        • 解决方案 fiber
    • React 面试题1
    • React 面试题2
    • React 面试题3
    • React 面试题5
    • 仿jira项目笔记 项目起航:项目初始化与配置
    • 第6章 CSS 其实很简单 - 用 CSS-in-JS 添加样式
    • 第8章 Hook,路由,与 URL 状态管理
    • pro-components 源码学习
    • ant-design Spin组件封装
    • React 生命周期
  • 小程序

  • 跨端

  • Electron

  • WebGL&GIS

  • 浏览器

  • 面经

  • 其他

  • 大前端
  • React
仲灏
2022-07-04
目录

React 原理

  • 一种编程范式
  • 纯函数
  • 不可变值

# vdom 和 diff 算法

  • h 函数

  • vnode 数据结构

  • patch 函数

  • 只比较同一层级,不跨级比较

  • tag 不相同,则直接删掉重建,不再深度比较

  • tag 和 key,两者都相同,则认为是相同节点,不再深度比较

# JSX 本质

  • JSX 即 createElement 函数
  • 执行生成 vnode
  • patch(elem, vnode) 和 patch(vnode, newVnode)

# 合成事件

  • 所有事件挂载到 document 上(React17版本开始,事件就不再绑定到 document上了,放到了root组件上)
  • event 不是原生的,是 SyntheticEvent 合成事件对象
  • 和 Vue 事件不同,和 DOM 事件也不同

# 为何要合成事件机制?

  • 更好的兼容性和跨平台

  • 载到 document,减少内存消耗,避免频繁解绑

  • 方便事件的统一管理(如事务机制)

# React 17 事件绑定到 root

  • React 16 绑定到 document
  • React 17 事件绑定到 root 组件
  • 有利于多个 React 版本并存,例如微前端

# setState 和 batchUpdate

  • 有时异步(普通使用),有时同步 ( setTimeout、 DOM 事件)
  • 有时合并(对象形式),有时不合并(函数形式)
  • 后者比较好理解(像 Object.assign ),主要讲解前者

# 核心要点

# setState 主流程

image-20220704110728020

# batchUpdate 机制

哪些能命中 batchUpdate 机制

  • 生命周期(和它调用的函数)
  • React 中注册的事件(和它调用的函数)
  • React 可以“管理〞的入口
# transaction 事务机制
 * <pre>
 *                       wrappers (injected at creation time)
 *                                      +        +
 *                                      |        |
 *                    +-----------------|--------|--------------+
 *                    |                 v        |              |
 *                    |      +---------------+   |              |
 *                    |   +--|    wrapper1   |---|----+         |
 *                    |   |  +---------------+   v    |         |
 *                    |   |          +-------------+  |         |
 *                    |   |     +----|   wrapper2  |--------+   |
 *                    |   |     |    +-------------+  |     |   |
 *                    |   |     |                     |     |   |
 *                    |   v     v                     v     v   | wrapper
 *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
 * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
 * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | +---+ +---+   +---------+   +---+ +---+ |
 *                    |  initialize                    close    |
 *                    +-----------------------------------------+
 * </pre>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 组件渲染过程

  • props state
  • render0 生成 vnode
  • patch (elem, vnode)

组件初始化 -> render 方法 -> 生成虚拟DOM -> React.DOM.render 方法 -> 真实DOM

组件更新 -> render 方法 -> 生成新的虚拟DOM -> diff算法 -> 定位出两次虚拟DOM的差异

render方法

image-20220704105512151

# 组件更新过程

  • setState(newState) --> dirtyComponents( 可能有子组件)
  • render0 生成 newVnode
  • patch(vnode, newVnode)

# 更新的两个阶段

  • 上述的 patch 被拆分为两个阶段:
  • reconciliation 阶段一执行 diff 算法,纯JS 计算
  • commit 阶段-将 diff 结果渲染 DOM

# fiber 性能

# 可能会有性能问题

  • JS是单线程,且和 DOM 渲染共用一个线程
  • 当组件足够复杂,组件更新时计算和渲染都压力大
  • 同时再有 DOM 操作需求(动画,鼠标拖拽等),将卡顿

# 解决方案 fiber

  • 将 reconciliation 阶段进行任务拆分 (commit 无法拆分)
  • DOM 需要渲染时暂停,空闲时恢复
  • window.requestldleCallback
#React#原理
上次更新: 2022/08/14, 18:25:44
react-router 使用
React 面试题1

← react-router 使用 React 面试题1→

最近更新
01
vim日常使用记录
04-02
02
滑动窗口最大值
04-02
03
有效的字母异位词
04-02
更多文章>
Theme by Vdoing | Copyright © 2021-2025 izhaong | github | 蜀ICP备2021031194号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式