【问题标题】:Will a React component re-render if its props are updated, but don't change in value?如果 React 组件的 props 更新但值没有改变,它会重新渲染吗?
【发布时间】:2018-08-30 20:34:11
【问题描述】:

假设我们有一个看起来像这样的 redux 商店:

{
  "page1": {
    "title": "Demo",
    "content": "Testing"
  },
  "page2": {
    "title": "Demo",
    "content": "Yes, I'm aware the titles match."
  }
}

现在让我们看看渲染标题的组件:

const Title = ({title}) => <h1>{title}</h1>

const mapStateToProps = state => ({
  title: getCurrentPage().title
})

export default connect(mapStateToProps)(Title)

在上面的代码块中,getCurrentPage() 是一个记忆函数(通过重新选择),它根据某些条件(在本例中为 react-router 的 location.pathname)从状态中获取当前页面数据。

当 getCurrentPage() 返回的数据不同时,即使 {title} 的具体值保持不变,该组件是否会重新渲染?

如果是,记忆派生的 title 属性是否会将答案变为否?

【问题讨论】:

    标签: javascript reactjs redux react-redux reselect


    【解决方案1】:

    好的,我花时间测试我自己的问题,因为我收到的第一个答案说它会重新呈现。我将 console.log('render') 插入到 Title 组件中,然后在两个单独的页面之间导航,每个页面共享相同的确切标题。结果……(鼓声)

    否。该组件没有重新渲染。

    【讨论】:

      【解决方案2】:

      如果 props 发生变化,或者由于调用 setState() 导致本地状态发生变化,或者您显式调用 foceUpdate() 函数,组件将重新渲染。在您的情况下,标题是一个字符串,并且旧字符串和新字符串具有相同的值,因此道具没有变化,因此不会重新渲染。

      需要注意的一点是将对象传递给道具。 react 不会做深度比较,所以结果可能与你的预期不同。这种情况下,你需要自己对比getDerivedStateFromProps或旧版本componentWillRecieveProps中的新旧对象,然后再决定是否需要调用forceUpdate()强制组件重新渲染。

      【讨论】:

        【解决方案3】:

        在我的测试中没有使用 redux 和对象,我已经在我的组件中添加了一个检查命令,以便仅在真正更改时更新。

        顺便说一句,为什么不使用简单的 console.log 进行测试?

        【讨论】:

        • 我终于在上面提到的特定条件(redux、reselect、react router)下自己运行了一个测试,组件没有重新渲染。我不知道您是如何设置测试的,但是如果没有 redux,我认为它一定依赖于从父组件传递下来的 props。这可能会导致不同的结果。
        • 很好奇@StefanBD 提到的案例可能是对象道具,而不是像您的字符串标题示例那样的标量类型道具。在这种情况下,React 可能会使用 ===(用于对象,简单的引用检查)。
        • yap Will Cain 是正确的,我使用了对象 {a:1, b:2, c:3} 并更新了对象中的一个值,所以对我的反应重新渲染一切,结果导致巨大的性能灾难我不得不用组件作弊应该更新功能
        猜你喜欢
        • 2018-03-26
        • 1970-01-01
        • 1970-01-01
        • 2020-08-01
        • 2019-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-30
        相关资源
        最近更新 更多