likes
comments
collection
share

React 常见概念浅析

作者站长头像
站长
· 阅读数 19

最近又重新捡起了对 React 源码的学习,很多知识都忘记了,重新复习的时候感觉又有新的收获。很多时候都是这样,第一次看得时候云里雾里,经过一段时间实践之后,再回头看,觉得恍然大悟,所以不要放弃对艰难知识的学习。

这些概念也是 React 中的基础,在深入理解 React 之前是必须掌握的。

数据驱动

对于现代框架而言,都可以使用一个经典公式表示工作流程: UI=fn(state)UI = fn(state)UI=fn(state)

  • UI 表示页面展示
  • state 表示数据
  • fn 表示更新的原理

不同的框架 fn 所表示的更新原理不同,但是整体来看都遵循以上的规则。

为什么需要数据驱动?上述的公式满足经典的 MVC 架构:将数据,视图和逻辑分离,能够方便开发和维护。再开发中我们根据 MVC 架构分别开发不同的部分,最终由框架来自动处理更新的逻辑。与以往的原生 JS 开发相比更加可维护。并且结合模块化,能够提高组件的可复用性。

const Button = () => {
	// 数据 Model
  const [count, setCount] = useState(0);
	
	// 逻辑 Control
  const handleClick = () => {
    setCount(count++);
  };

	// 视图 View
  return <div>{{ count }}</div>;
};

VDOM

虚拟DOM(Virtual DOM) 是一种实现快速更新的技术,通过计算得出需要更新的结果。在 JS 中可以使用对象来实现,最重要的是如何减少 VDOM 的计算。

为什么需要 VDOM,而不使用 DOM?

DOM 是根据 HTML 解析后的数据,其中包含了众多属性,相对而言 DOM 显得更加冗余。对于 VDOM 最重要的是如何减少计算次数,于是在 React 中通过 Fiber 实现了 VDOM,并且内部进行了一系列优化,以减少计算。

如何生成 VDOM?

在组件初始化时,调用 React.CreateRootDom(root).render(<App />),从根节点开始依次生成 FiberNode 最终组成 Fiber Tree。更新时,仍然从根节点开始遍历,通过 diffProps 判断是否有更新,有更新则进行相应处理,没有更新则可以复用 FiberNode。

时间切片

时间切片(Time Slice) 是 React 实现中创新的一点,我们可能会遇到这样的场景:在 VDOM 阶段面临上千条数据更新,此时进行 diffProps 可能需要很长时间,且一旦开始无法暂停,导致主线程占用无法及时响应其他操作。

时间切片正是将 VDOM 中耗时的任务,切分成更短的任务(默认时长 5ms),并且通过统一调度,当出现更高优先级的任务时,出让主线程;高优先级任务完成后,恢复执行的功能。

批量更新

批量更新(Batched Updates) 是一种性能优化手段,如下代码:

const Button = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count+1);
    setCount(count+1);
    setCount(count+1);
		setCount(count+1);
  };

	// 注意:点击后 count 只会增加 1,不会增加 3
  return <div onClick={handleClick}>{ count }</div>;
};

触发点击事件后,只会进入一次 render 阶段,这种将“多次更新流程合并为一次处理的技术”,被称为 Batched Updates。

React 常见概念浅析

但对于异步事件而言,情况稍有不同:每次点击会触发两次打印,因为异步事件不能自动批量更新。

React 常见概念浅析

React 在 v18 中改善了这种情况,即使异步也能触发自动批量更新,叫做 Automatic Batching

事件系统

为了抹平宿主环境之间的差异,React 实现了一套事件系统,对于 ReactDOM 宿主环境,这套系统包括:合成事件和事件传播机制

  • 合成事件(SyntheticEvent):是对浏览器原生事件的一层封装,兼容主流浏览器。同时拥有主流浏览器API,如 stopPropagation 和 preventDefault。合成事件的目的是消除浏览器事件的差异。
  • 事件传播机制:利用事件委托的原理,React 基于 Fiber Tree 实现了“捕获、目标、冒泡”的流程,并在机制中加入事件优先级,自定义事件名等特性。

总结

本文介绍了一部分 React 的专有名词,可以发现作为一个”用于构建 Web 和原生交互界面的库”,React 自己实现了 VDOM 和事件系统,基于此核心功能,React 能够根据不同的宿主环境进行扩展,反展为一个全平台的框架;作为一个“重运行时”的框架,React 提出一系列创新的优化方案,如:时间切片,批量更新等。

每个部分都体现了 React 团队在不断前进的道路上而做出的努力,其中的设计思想和实现方式值得大家深入的学习。