React 渲染的视觉指南 – 它总是重新渲染
2021 年 7 月 20 日
React 组件什么时候重新渲染? 是在它的状态或道具发生变化时吗?
看看上面的gif ?
应用程序的结构是: App > A > B > C
.
这是一个稍微简化的代码:
const App = () => {
// 状态
返回 (
< 组件A />
)
}
const ComponentA = () => < ComponentB />
const ComponentB = () => < ComponentC />
复制代码
组件 A 、 B 和 C 没有任何道具或状态。 然而,当应用程序呈现时,它们仍然会重新呈现。
在正常渲染中,React 并不关心“props 是否改变”——它会无条件地渲染子组件,因为父组件渲染了!
Mark Erikson – React 渲染行为的(大部分)完整指南
为了进一步说明这一点,让我们为每个组件添加一个状态并跟踪其行为。
当 的状态 C 改变时,只有 C 渲染。 但是当 的状态 B 改变时, B 和 C 都会 渲染。 在 乙 渲染,因为它的状态更新,并 ç 渲染,因为它的父呈现。
当 的状态 A 改变时, A 因为状态更新 B 而 因为 A 渲染, 渲染而渲染, C 因为 B 渲染而渲染。
避免重新渲染
有几种方法可以避免 React 中不必要的重新渲染。 在这篇文章中,我将只关注 React.memo
并为以后的帖子保存其他方法。 如果您对替代品感兴趣 memo
查看 Dan Abramov 的 Before you memo() 。
另外请记住,在这篇文章中,我只探讨了由直接状态更新或父渲染引起的重新渲染。 我不传递任何道具。
如果您将组件包装在 memo
,当它的父渲染时它不会重新渲染。
请注意, C 会 在其状态更改时更新,但不会在父渲染时更新。
提起备忘录
让我们举起 memo
起来看看会发生什么。
组件 的状态更新 A 、 B 和 C 产生与之前相同的结果。 但请注意 App 上的状态更新。 包裹一个组件 memo
阻止该组件的整个子树响应父渲染而重新渲染。
这就是为什么你可以听到这样的建议:
相邻的组件呢?
相同的规则适用于相邻的组件。 该组件与 memo
不会响应父渲染而重新渲染,因此,阻止其整个子树重新渲染。
我应该记下所有内容吗?
如果 memo
对性能有如此大的影响,用它包装所有东西有意义吗? 嗯,不是真的。 但这是另一天的话题。 如果您有兴趣,请阅读 修复缓慢的渲染,然后再修复 的重新渲染 Kent C. Dodds 。