在React中,当父组件重新渲染时,是否props未更改的子组件不需要重新渲染?

2023-11-22

我认为事实是,当父组件在 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) 的一篇精彩文章:在你备忘录之前()。对于你的问题我考虑两点:

  1. 将来编译器可能会决定何时记忆组件。

  2. 组件渲染并不意味着它的所有子组件都会被重新渲染。

这是一个例子:

const ParentComponent = ({ children }) => {
  const [state, setState] = useState(0);
  return <div>{children}</div>
}

如果我们更新状态,子项将不会被重新渲染。 React 仅使用先前的值。这是一个肯特·C·多布斯的文章关于这个优化技术。

最后一件事。React.memo and useMemo是不同的。第一个用于组件记忆,第二个是用于昂贵计算的挂钩。还有shouldComponentUpdate对于类组件和PureComponent它不仅比较道具,还比较状态。

希望答案和链接能够对这个主题有所启发。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在React中,当父组件重新渲染时,是否props未更改的子组件不需要重新渲染? 的相关文章

随机推荐