【问题标题】:How to avoid to re-render children when updating style via props or state in React?在 React 中通过 props 或 state 更新样式时如何避免重新渲染孩子?
【发布时间】:2018-03-14 01:25:56
【问题描述】:

在我的应用程序的根目录中,我有两个 React 组件,Menu 和 Main。菜单通过将其平移到视口的左侧而被隐藏。当它可见时,我还希望将主要内容翻译到右侧。为此,我只需将 menuOpened 属性(布尔值)传递给两个组件。它将应用设置 CSS 变换属性 translateX() 的条件样式。问题是,当我更新道具时,所有的孩子都会重新渲染。有没有更好的做法来改变组件的样式/状态/道具?

【问题讨论】:

  • 所有孩子重新渲染有什么问题?如果您除了顶级容器的样式属性之外没有修改任何内容,这应该很快。
  • 也许我高估了这个问题。我认为重新渲染所有内容很奇怪,因为我只更改了一个 CSS 属性。
  • 您不会重新渲染所有内容。请参阅下面的评论:)
  • 了解 react 的渲染方式:它计算组件在其 props 或 state 发生变化时发生变化(如果不是全部,子树中的大多数组件都不是这种情况),然后构建一个虚拟 DOM,然后将虚拟 DOM 与实际 DOM 进行比较,并且仅在此时开始修改实际 DOM(这是循环中最昂贵的部分)。这就是它的酷炫之处:它永远不会丢弃所有页面并在每次单个 prop 值更改时重新渲染它。

标签: javascript css reactjs


【解决方案1】:

您可以向您的应用程序容器添加一个附加类(例如app_with-menu),以指示菜单是否打开。然后像这样在 CSS 中设置样式:

.app .content {
   // style for content when menu is closed
}
.app.app_with-menu .content {
   // style for content when menu is opened
}

【讨论】:

  • 我相信将 className 添加到 App 容器中也会触发组件的重新渲染。我不是 10000% 确定,但我不明白为什么不会。
  • 您更新了组件的道具。这会导致 React 计算 DOM 树的差异,并运行受影响组件的生命周期方法。
【解决方案2】:

正如评论所述 - “重新渲染”并不昂贵。由于 DOM 树中几乎没有任何变化,差异很小,因此实际变化很小。

但是如果你真的想控制一个组件何时重新渲染,你可以使用 React 生命周期方法shouldComponentUpdate(...)

【讨论】:

  • 也许我高估了这个问题。我认为重新渲染所有内容很奇怪,因为我只更改了一个 CSS 属性。
  • 不,没关系。您不是在“重新渲染”所有内容。 React 正在计算差异,并且只是“重新渲染”差异。
  • 好吧,但是如果我有一个用 Array.map() 渲染一个 looong 数组的组件怎么办。即使是完全相同的列表,是否还需要时间来比较所有孩子? (尤其是在旧的移动设备上)。
猜你喜欢
  • 2016-12-30
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 1970-01-01
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多