了解 useEffect() 行为和额外的重新渲染

Gre*_*Woz 2 javascript reactjs react-hooks

我正在使用以下虚拟组件进行一些测试,在执行时(在控制台中)我得到以下结果:

Rendering:  0
Triggered:  0
Rendering:  4
Triggered:  4
Rendering:  4
Run Code Online (Sandbox Code Playgroud)

我很难理解为什么。

第一个渲染:

  • 设置index0.
  • undefined按原样运行 useEffect0
  • useEffect 请求设置index4

第二次渲染:

  • index4
  • 为什么useEffect主体又被执行了?

第三次渲染:

  • 为什么会出现重新渲染?

我所期望的是:

Rendering:  0
Triggered:  0
Rendering:  4
Run Code Online (Sandbox Code Playgroud)

我是否跳过了一些非常明显的事情?您能帮我了解它的幕后工作原理吗?

Rendering:  0
Triggered:  0
Rendering:  4
Triggered:  4
Rendering:  4
Run Code Online (Sandbox Code Playgroud)
Rendering:  0
Triggered:  0
Rendering:  4
Run Code Online (Sandbox Code Playgroud)

Mar*_*vic 5

重新渲染的次数实际上是正确的。我们来分析一下会发生什么:


  1. 渲染 0 - 这是在安装时第一次渲染(在这种状态下,每个渲染useEffect都会自动运行)

  1. 已触发 0 - 这是初始触发useEffect

  1. 渲染 4 - 此重新渲染是因为您将新状态设置index4

  1. 已触发 4 - 这是因为您index从 0 更改为 4 而触发

  1. 渲染 4 - 这是运行,因为状态从 变为44即使值相同,也会触发组件重新渲染,因为 React 不知道您是否设置相同的状态,并且需要再次运行)。在此重新渲染中,useEffect未运行,因为index再次为 4。

基本原理

如果组件中的任何点(例如useState useContext、 )发生任何变化customHook,则该组件将需要重新渲染。如果父组件重新渲染,即使您的组件没有任何更改,子组件也会重新渲染,也会发生这种情况。

其他重新渲染提示和信息

为了防止父级不必要地重新渲染子组件,您可以使用React.memo,如果 props 发生变化,这将重新渲染您的组件,但如果状态或上述任何钩子发生变化,则不会阻止您的组件重新渲染。

如果这看起来多余,那么听起来确实如此,但这是必要的,以便 React 确保它具有最新状态。像这样运行 JS 比使用一些状态内存来检查更改更快,而且对开发人员来说更透明(以及如何创建VDOM )