我认为事实是,当父组件在 React 中重新渲染时,通常所有子组件也会重新渲染。
我做了一个实验来证实:
https://codesandbox.io/s/currying-pine-r16rzi
return (
<div>
<div>Time now is {timeNow.toLocaleTimeString()}</div>
<TheTimeNow /><TheTimeNow />
</div>
);
Run Code Online (Sandbox Code Playgroud)
该父组件重新渲染,并且<TheTimeNow />props 值没有变化(它没有),但它仍然重新渲染并显示更新时间。
我认为React实际上改变了DOM是不一样的,因为我认为其机制是React使用以前的虚拟DOM与新的虚拟DOM进行比较,并根据需要仅更新最小的实际DOM节点document.documentElement。
如果您使用 Google Chrome 并在时间语句上执行 Inspect Element,就可以看到这一点:只有时间部分发生变化,其他英文单词保持不变。与此相比,如果是纯 JavaScript,则所有节点都会发生变化: https: //jsfiddle.net/8sj2ugae/1/,当您执行 Inspect Element 时。
然而,我们不能说,如果一个孩子是<Foo />并且由于没有传递给它的道具,那么<Foo />真的不应该改变,并且调用是浪费的Foo()?(如果Foo是函数组件,或者render()如果是类组件则调用该方法。)
现在,由于所有子项都会重新渲染,这意味着它们的所有子项也会重新渲染。递归地重复这个规则,这意味着整个子树被重新渲染。
我的问题是:如果他们的道具没有改变,他们是否真的不需要重新渲染,或者是否有其他因素使他们真的需要重新渲染?
答案是肯定的,不需要重新渲染。但为了了解这一点,我们需要将新道具与以前的道具进行比较。而且这个操作并不是免费的。
此外,如果我们进行浅层比较,就会增加出现错误的可能性。有人可能期望在深度 props 更新后重新渲染。
应该React.memo是默认行为吗?在大多数情况下它会提高性能吗?我们不知道。没有证据证明这一点。马克·埃里克森 (Mark Erikson) 的帖子对此有更多介绍。
这是 Dan Abramov 写的一篇很棒的文章:Before You memo()。对于你的问题我考虑两点:
将来编译器可能会决定何时记忆组件。
组件渲染并不意味着它的所有子组件都会被重新渲染。
这是一个例子:
const ParentComponent = ({ children }) => {
const [state, setState] = useState(0);
return <div>{children}</div>
}
Run Code Online (Sandbox Code Playgroud)
如果我们更新状态,子项将不会被重新渲染。React 仅使用先前的值。这是Kent C. Dobbs 撰写的关于这种优化技术的文章。
最后一件事。React.memo并且useMemo是不同的。第一个用于组件记忆,第二个是用于昂贵计算的挂钩。还有shouldComponentUpdate类组件,PureComponent它们不仅比较道具,还比较状态。
希望答案和链接能够对这个主题有所启发。
| 归档时间: |
|
| 查看次数: |
1713 次 |
| 最近记录: |