React 什么时候重新渲染子组件?

7

我知道当状态或属性改变时(或者我们强制组件重新渲染),React会执行重新渲染。我还知道,当组件重新渲染时,React会重新渲染其子组件。

我注意到,即使子组件的属性(子属性)没有改变,React也会重新渲染子组件,因此父组件传递与先前相同的属性时也是如此。

为什么会这样?React是否会重新渲染完全没有状态和属性的子组件?

2个回答

4
如果你想让子组件不重新渲染,你应该使用React.memoPureComponentshouldComponentUpdate生命周期钩子。这三个选项告诉React,如果组件的输入(props)没有改变,那么重新渲染组件就没有意义,因为组件不会改变。
如果你正在使用类组件,PureComponent或shouldComponentUpdate应该是你的首选。基本上,PureComponent只是为你实现了shouldComponentUpdate。
当使用函数组件时,React.memo应该是你的首选。而且,React.memo有一个第二个参数用于确定相等性,它的作用类似于shouldComponentUpdate。
在处理react组件时,你应该绝对优先使用这三个选项,而不是reselect。Reselect是用来记忆redux中的选择器(或普通函数调用)的,它不是用来记忆react组件的。

通常我使用reselect来使组件的props稳定(在使用connect时),并防止在每次渲染时重新计算复杂数据。


非常感谢,现在我明白了。 - Karol
嗨,我有另一个问题,它与当前的问题不太相关。所以当React在每个组件中首次调用构造函数,然后将其挂载时,例如我们更改页面(使用react-router)或仅单击某些内容使我们的组件不可见且不在屏幕上。然后回来再次查看我们的组件,我们会再次挂载此组件,但是构造函数是否再次被调用? - Karol
是的,每当组件从页面中移除时,再次添加到页面中时都必须重新挂载该组件。每当组件挂载时,整个生命周期都会重新开始,包括构造函数和componentDidMount。 - Zachary Haber
非常感谢,这真的很有帮助。 - Karol
根据React文档:“这个[React.memo]方法只是作为性能优化而存在。不要依赖它来“防止”渲染,因为这可能会导致错误。”基于此,我不确定您是否应该使用React.memo,或者我有什么遗漏的地方吗? - Joel Brighton
你应该绝对使用它来提高应用程序在关键组件中的性能。但是,你不能依赖于组件永远不会重新渲染。通常,如果你使你的组件纯净,那么你就不需要担心它们重新渲染。在这种情况下,一个不好的例子是直接将副作用 API 调用放在渲染函数中(在 useEffect 之外),因为你期望由于 React.Memo 只调用一次。这不是它的目的。React.Memo 向 React 发出信号,表明你的组件不需要重新渲染,而不是不能重新渲染。 - Zachary Haber

1
React默认这样做是因为它不知道在状态相同时不重新渲染,除非你使用像reselect这样的包对这些组件进行记忆化处理。
Reselect帮助你只在传递的状态与当前状态不同时重新渲染组件。

在这里使用PureComponent或React.Memo也是一个选项吗?它可以代替reselect包使用吗? - Karol
我不了解其他的包,因为我只使用过 Reselect。但只要它们都提供记忆化功能,就应该可以工作。只需阅读其文档以了解它们提供什么以及如何集成即可。 - Victor Whyte
PureComponent 和 React.Memo 是 React 内置的组件/方法。 - Karol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接