【问题标题】:Re-render React component after props change道具更改后重新渲染 React 组件
【发布时间】:2020-12-24 17:03:12
【问题描述】:

在 React 文档中,它说

默认情况下,当你的组件的 state 或 props 发生变化时,你的组件会重新渲染。

我了解状态更改,但我不确定道具何时更改。据我所知,道具总是从父组件传递到子组件。并且当父组件重新渲染时(例如由于状态更改),所有子组件也会重新渲染(忽略 shouldComponentUpdate)。所以在我看来,如果父组件重新渲染,所有子组件都会重新渲染,无论我是否将新的道具传递给它们。如果我确实将新道具传递给子组件,那么子组件重新渲染的事实仅仅是因为父组件正在重新渲染,而不是因为我正在传递新道具。

是否存在父组件将新的props传递给子组件,导致子组件重新渲染,但又不是单纯由父组件重新渲染引起的场景?

是否有可能看到一个组件因为接收到新的 props 而不是因为父组件正在重新渲染(或它自己的状态发生变化)而重新渲染的示例?

对不起,如果这是一个基本问题,我是 React 新手。

编辑:我看到 Redux 可以通过传递新的 props 导致组件重新渲染,我很想知道 Redux 在幕后做了什么来实现这一点。

【问题讨论】:

  • 这是一个很好的问题。

标签: reactjs react-redux


【解决方案1】:

例如,当您将 provider、HOC 或 Redux 与 mapStateToProps 一起使用时,这些 props 会从其他注入组件的 props 中更改。

【讨论】:

  • 使用 mapStateToProps 的 HOC 或组件是否仍会重新渲染(称为渲染方法)?
  • 是的,你可以避免组件使用 shouldComponentUpdate 重新渲染,从而在某些道具发生变化时渲染。小心对象和数组,你必须深入比较值,因为引用会改变。
【解决方案2】:

我对做出反应并不陌生,我问的是同样的事情。有一篇文章让我明白了:https://thoughtbot.com/blog/react-rendering-misconception

如果需要 DOM 更新,则需要重新渲染以进行差异检查。如果你已经实现了 shouldComponentUpdate 或者用 memo 包裹(两者都返回 false),那么会跳过重新渲染。

如果子组件是使用 redux 或上下文连接的,那么即使没有重新渲染父组件,它也可能会重新渲染。

【讨论】:

  • 这篇文章不错,可能我的困惑在于实际的声明By default, when your component’s state or props change, your component will re-render.,而声明的props更改部分暗示该组件是用备忘录包裹的?
  • 这样看:组件的 props 可能是父组件的状态,这就是它的反应与它相似的原因。如果组件实现了 shouldComponentUpdate 或被包裹在备忘录中,那么无论父级是否更改,它都不会重新渲染(它仅在该方法中的给定条件下重新渲染)。是的,如果 props/state 没有改变但是父级重新渲染,那么整个树都会重新渲染(对于差异检查,可能不是真正的 DOM 更改)。这通常非常快,但是一旦渲染变得昂贵,shouldComponentUpdate 可以帮助您防止它。
【解决方案3】:

回答你最后提出的问题:

  • 如果孩子是 PureComponent 或包裹在 React.memo 中,它会在道具更改时重新渲染。如果父级重新渲染,则组件将比较它收到的道具,如果它们与之前传递的道具相同,则不会重新渲染。

  • 如果子级不是PureComponent 或包裹在React.memo 中,那么它会在其父级重新渲染时重新渲染。

【讨论】:

  • 这是有道理的,但我很想知道什么会导致组件首先重新渲染,而不是它的状态改变或父级重新渲染。我已将原始问题更新为更清晰。
  • 对您的组件连接到的任何 React context 的更改(如果有)。或者从组件调用this.forceUpdate()如果您使用 Redux: 您可以想象 connectmapStateToProps 在幕后所做的事情是创建一个组件,该组件从 Redux 获取一些 state 并将其作为 props 传递给它的孩子。该上下文中的子组件是您传递给 React-Redux 的 connect 函数的组件。
  • 我可能是错的,但是看看 Redux,似乎 Redux 创建了一个包装器组件,如果更新后的 Redux 状态会导致子组件的道具发生变化,则强制渲染这个包装器组件,因此导致子组件也重新渲染,现在使用新的道具。这与组件重新渲染不同,因为它的道具已经改变,如果你看到我来自哪里的话。很抱歉造成混淆,我只是想获得一个明确的例子,说明道具更改导致组件重新渲染的位置。另外,我认为上下文变化与道具变化不同。
  • Redux state映射props。因此,您从 mapStateToProps 返回的 Redux 状态 变为 props 用于组件。我不太清楚您要概述的区别是什么。上下文更改与 props 更改不同,但对于本次讨论而言没有意义,除非您实现 shouldComponentUpdate
【解决方案4】:
  1. redux 的连接中间件类似于订阅,每个子组件都可以通过订阅直接连接到 store,每当 store 发生变化时,store 都会尝试重新同步其所有连接的组件。任何组件的新传入数据都是作为导致重新渲染的道具。
  2. 任何从其状态之外更改的组件都只能通过 props 进行,因此它类似于父组件传递新数据/redux 存储将新数据推送到组件。

【讨论】:

    猜你喜欢
    • 2021-07-13
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2021-11-06
    • 2021-09-01
    • 2021-12-04
    • 1970-01-01
    • 2018-10-08
    相关资源
    最近更新 更多