React Hooks Flow:深入探究

许多开发人员都了解 React,但缺乏了解可能会导致对其工作原理的假设。清晰地了解 React 中的钩子流程可以大大提高您的代码质量。在使用 React 超过 4 年后,我想分享一些关于 React 钩子流程的重要见解,这是一个经常被忽视的概念。

在深入探讨 Hooks 流程之前,我想重新回顾一下 Hooks 的规则

**1. 只在顶层调用 Hooks**

不要在循环、条件或嵌套中调用 Hook

函数。相反,总是在顶层使用 Hooks

在任何早期返回之前,React 函数

**2. 仅从 React 函数调用 Hooks(组件或自定义 Hook)**

不要从常规 JavaScript 函数调用 Hooks。

**React Hooks 流程**

这个 React hooks 流程图有助于直观地展示在组件生命周期的不同阶段中钩子的调用顺序。

React hook flow diagram

让我们探索组件生命周期的每个阶段。

**初始挂载**

这是组件第一次加载到屏幕上的时候。

React component initial mount

**运行惰性初始化程序**

在 React 中,状态初始化在整个组件的生命周期中只发生一次。

我所说的“初始化”是指“useState”的初始值将仅分配给变量一次。

Image description

这很正常,通常不需要担心。但是,当初始化涉及复杂计算时,例如从本地存储设置状态,这一点就变得更加重要。

const [userList, setUserList] = useState(localStorage.getItem("usersList"))

目前,localStorage.getItem("usersList") 每次重新渲染时都会执行,但其结果不会分配给状态变量。这种重复评估可能会导致性能问题。为了避免这种情况,您可以在挂载阶段将回调函数传递给“useState”,该函数只会执行一次。

const [userList, setUserList] = useState(() => localStorage.getItem("usersList"))

这称为状态的延迟初始化,在此处了解更多信息

延迟初始化有助于防止每次重新渲染时运行不必要的初始化逻辑。

注意:仅当状态初始化涉及计算时才使用初始化函数。

**使成为**

在此步骤中,React 调用函数(组件)来生成该组件的虚拟 DOM 表示。此过程并不直接意味着该组件在屏幕上对用户可见。相反,它涉及 React 创建一个虚拟 DOM 对象来描述 UI 应该是什么样子。

以下是虚拟 DOM(VDOM)对象的示例:

const ComponentA = () => {
  return 

Hello World!

}

VDOM 对象

`{

$$typeof: 符号(react.element),

键:null,

道具:{children:'Hello World!'},

ref:null,

输入:“h1”,

.....

};`

**React 更新 DOM**

在生成虚拟 DOM 并协调它以获得最终的虚拟 DOM 之后,React 会相应地更新实际 DOM。

**运行 LayoutEffects**

此步骤涉及运行 `useLayoutEffect` 钩子,它类似于 `useEffect`,但在浏览器执行任何绘制之前执行,请参阅此处了解更多信息

**浏览器绘制屏幕**

浏览器将 DOM 绘制到屏幕上

**运行效果**

这是 `useEffect` 钩子运行的步骤,即在浏览器上渲染 UI 之后

如果 useEffect 中的状态更新,则会触发组件的更新生命周期

**更新**

当任何状态更新被触发时,都会触发组件的更新生命周期

Image description

**渲染**,**React 更新 DOM**

这些步骤与安装阶段类似

**清理布局效果**

在创建虚拟 DOM(VDOM)并更新实际 DOM 之后,React 运行“useLayoutEffect”钩子的清理函数。

注意:如果 `useLayoutEffect` 的依赖项没有改变,则其清理函数将不会运行。

**运行 LayoutEffects**

如果任何依赖项比较返回 false,表示发生变化,则 `useLayoutEffect` 将再次运行;否则,则不会运行。

**浏览器绘制屏幕**

此时,浏览器将更新后的 DOM 渲染到屏幕上。

**清理效果**、**运行效果**

仅当依赖项与上一次渲染相比发生变化时,才会执行 `useEffect` 清理和执行。如果没有依赖项发生变化,则清理函数和效果都不会运行。

**卸载**

这是组件生命周期的最后阶段,此阶段中,组件从 DOM 中移除并且对用户不再可见。

Image description

**清理布局效果**、**清理效果**

从 DOM 中删除组件之前,React 会运行 `useLayoutEffect` 和 `useEffect` 钩子的所有清理函数。

下次您在 UI 中遇到错误时,请可视化钩子流以在代码中精确定位正确的位置来调查和解决问题。我希望这能帮助您提高编码技能。祝您编码愉快!