ReactJS 教程

ReactJS - 主页 ReactJS - 简介 ReactJS - 路线图 ReactJS - 安装 ReactJS - 功能 ReactJS - 优势和缺点 ReactJS - 架构 ReactJS - 创建 React 应用程序 ReactJS - JSX ReactJS - 组件 ReactJS - 嵌套组件 ReactJS - 使用组件 ReactJS - 集合组件 ReactJS - 样式 ReactJS - 属性 (props) ReactJS - 使用属性创建组件 ReactJS - props 验证 ReactJS - 构造函数 ReactJS - 组件生命周期 ReactJS - 事件管理 ReactJS - 创建事件感知组件 ReactJS - Expense Manager 事件 ReactJS - 状态管理 ReactJS - 状态管理 API ReactJS - 无状态组件 ReactJS - Hooks 进行状态管理 ReactJS - Hooks 的组件生命周期 ReactJS - 布局组件 ReactJS - 分页 ReactJS - Material UI ReactJS - Http 客户端编程 ReactJS - 表单编程 ReactJS - 受控组件 ReactJS - 非受控组件 ReactJS - Formik ReactJS - 条件渲染 ReactJS - 列表 ReactJS - Key 键 ReactJS - 路由 ReactJS - Redux ReactJS - 动画 ReactJS - Bootstrap ReactJS - Map ReactJS - 表格 ReactJS - 使用 Flux 管理状态 ReactJS - 测试 ReactJS - CLI 命令 ReactJS - 构建和部署 ReactJS - 示例

Hooks

ReactJS - Hooks 简介 ReactJS - 使用 useState ReactJS - 使用 useEffect ReactJS - 使用 useContext ReactJS - 使用 useRef ReactJS - 使用 useReducer ReactJS - 使用 useCallback ReactJS - 使用 useMemo ReactJS - 自定义 Hooks

ReactJS 高级

ReactJS - 可访问性 ReactJS - 代码拆分 ReactJS - 上下文 ReactJS - 错误边界 ReactJS - 转发 Refs ReactJS - 片段 ReactJS - 高阶组件 ReactJS - 与其他库集成 ReactJS - 优化性能 ReactJS - Profiler API ReactJS - Portals ReactJS - 不使用 ES6 ECMAScript ReactJS - 不使用 JSX 的 React ReactJS - Reconciliation ReactJS - Refs 和 DOM ReactJS - 渲染道具 ReactJS - 静态类型检查 ReactJS - 严格模式 ReactJS - Web 组件

其他概念

ReactJS - 日期选择器 ReactJS - Helmet ReactJS - 内联样式 ReactJS - PropTypes ReactJS - BrowserRouter ReactJS - DOM ReactJS - 轮播 ReactJS - 图标 ReactJS - 表单组件 ReactJS - 参考 API

ReactJS 有用资源

ReactJS - 快速指南 ReactJS - 备忘录 Axios - 备忘录 ReactJS - 有用资源 ReactJS - 讨论


ReactJS - Reconciliation

Reconciliation 是 React 库的一个内部过程。我们知道,React 应用程序会创建一个虚拟 DOM,然后根据虚拟 DOM 更新应用程序的实际 DOM。每当 React 收到更新请求时,它都会首先创建一个虚拟 DOM,然后使用不同的差异算法将虚拟 DOM 与之前的状态进行比较,然后只有在绝对必要时才会更新 DOM。

尽管差异算法和更新 DOM 是 React 核心内部的,但了解一些内部内容将有助于我们调整应用程序以最大限度地利用 React 库。

差异算法

让我们在本章中看看 React 核心应用的一些差异算法。

  • 相同类型的元素

  • 每当 React 组件将元素从一种类型更改为另一种类型(例如从 div 更改为更具体的 p)时,整个 React 虚拟 DOM 树都会发生变化并触发 DOM 更新。

<!-- Before -->
<div>
   <Content />
</div>
<!-- After -->
<p>
   <Content />
</p>

此时,整个元素将得到更新。

  • 相同类型的 DOM 属性。

  • 当元素类型相同时,react 将检查属性是否存在差异。如果 react 发现属性及其值有任何新变化,则它将仅更新已更改的属性。

<!-- Before -->
<div className="someClass">
   <Content />
</div>
<!-- After -->
<div className="someOtherClass">
   <Content />
</div>

此处,只有 DOM 实例的类属性会得到更新。

  • 相同类型的 DOM 属性(样式)。

  • 当元素属于相同类型并且 React 发现样式属性存在差异时,它将仅更新样式的属性。

<!-- Before -->
<div style={{fontFamily: 'Arial'}} />
   <p> ... </p>
</div>
<!-- After -->
<div style={{color: 'red', fontFamily: 'Arial'}} />
   <p> ... </p>
</div>

此处,只有 div 元素样式的颜色属性会被更新

  • 相同类型的组件元素 − 每当 React 看到相同的 React 组件类型时,它就会调用 componentWillUpdate 事件和 React 组件的其他更新事件,以便组件更新其状态。然后,它将调用组件的 render 方法,算法会递归

  • 相同类型的子元素集合 − 每当 React 看到相同类型的子元素集合时,它就会按顺序检查元素是否存在差异。因此,如果我们有一个新的第一个子元素,那么整个集合都会得到更新。

<!-- Before -->
<ul>
   <li>Peter</li>
   <li>Olivia</li>
</ul>
<!-- After -->
<ul>
   <li>John</li>
   <li>Peter</li>
   <li>Olivia</li>
</ul>

此处,由于第一个元素 (li) 是更新元素,因此整个元素 (ul 元素的子元素) 将得到更新。

为了解决这个问题,我们可以引入一个 key 属性,如下面的代码片段所示。React 为此有一个特殊的 key 属性。

<!-- Before -->
<ul>
   <li key="1">Peter</li>
   <li key="2">Olivia</li>
</ul>
<!-- After -->
<ul>
   <li key="3">John</li>
   <li key="1">Peter</li>
   <li key="2">Olivia</li>
</ul>

总结

React 尝试在每次发布中优化 diffing 算法,以确保更新最少。最少的更新意味着应用程序的性能更好。了解内部情况并遵循最佳实践进行相应的编码,我们可以成倍地提高应用程序的性能。