我认为事实是,当父组件在 React 中重新渲染时,通常所有子组件也会重新渲染.
我做了一个实验来证实:
https://codesandbox.io/s/currying-pine-r16rzi
return (
<div>
<div>Time now is {timeNow.toLocaleTimeString()}</div>
<TheTimeNow /><TheTimeNow />
</div>
);
该父组件重新渲染,并且<TheTimeNow />
道具值没有变化(没有),但它无论如何都会重新渲染并显示更新的时间。
我认为React实际上改变了DOM是不一样的,因为我认为其机制是React使用以前的虚拟DOM与新的虚拟DOM进行比较,并仅更新minimal实际 DOM 节点document.documentElement
如所须。
如果您使用 Google Chrome 并在时间语句上执行 Inspect Element,就可以看到这一点:只有时间部分发生变化,其他英文单词保持不变。与此相比,如果是纯 JavaScript,则所有节点都会发生变化:https://jsfiddle.net/8sj2ugae/1/当您执行检查元素时。
然而,我们不能说,如果一个孩子<Foo />
由于没有传递给它的 props,那么<Foo />
确实不应该改变,而且调用起来很浪费Foo()
? (if Foo
是一个功能组件,或者调用render()
方法(如果它是类组件)。)
现在,由于所有子项都会重新渲染,这意味着它们的所有子项也会重新渲染。递归地重复这个规则,这意味着整个子树被重新渲染。
我的问题是:如果他们的道具没有改变,他们是否真的不需要重新渲染,或者是否有其他因素使他们真的需要重新渲染?
答案是肯定的,不需要重新渲染。但为了了解这一点,我们需要将新道具与以前的道具进行比较。而且这个操作并不是免费的。
此外,如果我们进行浅层比较,就会增加出现错误的可能性。有人可能期望在深度 props 更新后重新渲染。
Should React.memo
是默认行为吗?在大多数情况下它会提高性能吗?我们不知道。没有证据证明这一点。有关此内容的更多信息,请参见马克·埃里克森的帖子.
这是丹·阿布拉莫夫 (Dan Abramov) 的一篇精彩文章:在你备忘录之前()。对于你的问题我考虑两点:
-
将来编译器可能会决定何时记忆组件。
-
组件渲染并不意味着它的所有子组件都会被重新渲染。
这是一个例子:
const ParentComponent = ({ children }) => {
const [state, setState] = useState(0);
return <div>{children}</div>
}
如果我们更新状态,子项将不会被重新渲染。 React 仅使用先前的值。这是一个肯特·C·多布斯的文章关于这个优化技术。
最后一件事。React.memo
and useMemo
是不同的。第一个用于组件记忆,第二个是用于昂贵计算的挂钩。还有shouldComponentUpdate
对于类组件和PureComponent
它不仅比较道具,还比较状态。
希望答案和链接能够对这个主题有所启发。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)