即使该组件的道具或状态没有改变,也会调用 React shouldComponentUpdate()

Posted

技术标签:

【中文标题】即使该组件的道具或状态没有改变,也会调用 React shouldComponentUpdate()【英文标题】:React shouldComponentUpdate() is called even when props or state for that component did not change 【发布时间】:2016-07-28 22:14:54 【问题描述】:

我在我的 React 组件中添加了生命周期方法

  shouldComponentUpdate(nextProps, nextState) 
    console.log(nextProps, nextState);
    console.log(this.props, this.state);

    return false;  
  ,

我的问题是,即使 nextProps 和 nextState 与当前的 props 和状态完全相同,也会在组件上调用此方法。当我比较 nextProps 和 this.props 的 console.log 语句时,它们完全相同。与国家相同。

那么为什么调用 shouldComponentUpdate 呢?

每当我更改父组件的状态时都会调用它。但是实际组件上的任何道具或状态都没有改变。那为什么叫它呢?

fyi,我正在使用 React 和 Meteor

进一步说明:

我想知道为什么函数shouldComponentUpdate 首先被调用。该组件的状态或道具都没有改变。但是父组件的状态在变化。

【问题讨论】:

它被调用是因为你返回true,如果你返回false,它不会 好吧,我的问题是,为什么首先调用该函数。道具或状态没有改变。但我发现它被调用是因为父组件正在重新渲染,因此称为 shouldComponentUpdate。我认为... 这只是一个简短的评论,请在下面查看我的完整答案... 【参考方案1】:

shouldComponentUpdate 的目的是指示是否应该调用 render。在您的情况下,某些父组件已渲染并表示它还想渲染您的子组件的实例。

shouldComponentUpdate 是您让渲染短路并说“不要打扰,这里没有任何变化”的机会。

现在,对于您的问题,“既然没有任何改变,为什么还要调用它”? React 本身并不比较新旧 props。你可以得到一个 mixin 来为你做这件事(即PureRenderMixin),但默认情况下 React 只会让渲染运行。

React 本身不进行比较的原因有几个。首先,与分析 props 和 state 相比,跳过渲染的性能节省可以忽略不计。由于 React 的渲染机制已经优化以避免不必要的 DOM 操作,它可以假设组件需要更新并期望合理的性能。其次,进行比较并不完全直截了当。你的 prop 是原始的?不可变的?数组?复杂的对象?是否需要深度比较?

React 的模型是“默认情况下,我们将渲染所有询问的内容。如果您希望某些东西选择退出以提高性能,请继续通过实现 shouldComponentUpdate 告诉我们”。

【讨论】:

【参考方案2】:

React 自动调用shouldComponentUpdate,它在重新渲染过程开始之前触发(在这种情况下是你的父组件。)所以自然会被频繁调用。

此函数的默认实现返回 true,因此要停止重新渲染,您需要在此处返回 false:

  shouldComponentUpdate(nextProps, nextState) 
    console.log(nextProps, nextState);
    console.log(this.props, this.state);

    return false;  
  

Advanced Concerns, React page

因此,总而言之,React 通过允许用户使用 shouldComponentUpdate 来缩短进程,从而避免执行协调 DOM 子树所需的昂贵 DOM 操作,

【讨论】:

【参考方案3】:

shouldComponentUpdate() 每次都会被调用:

每次重新渲染父组件时都会更新道具。这包括使用完全相同的道具值进行重新渲染的所有场景。 通过调用setState()(react 允许的唯一方式)更新状态。这包括状态值完全相同的所有场景。

即使新值与旧值完全相同,有时让重新渲染周期通过也会很有用。例如。当您的组件通过 props 接收到用户 ID(可能未更改),并从某处获取新消息并将它们置于状态时。

此外,“shouldComponentUpdate()”作为一种单独的方法来检查更改并仅在发生更改时才更新,这使得代码易于维护:

制作第一个没有shouldComponentUpdate() 的版本,并确保相同的道具和状态集导致呈现相同的结果。 添加和调试shouldComponentUpdate()

调试接受输入(状态和道具)并呈现输出的“状态机”相对容易。 调试管理状态更改的机器要困难得多。

【讨论】:

【参考方案4】:
shouldComponentUpdate() – Returns true or false value based on certain conditions. 
If you want your component to update, return true else return false. 
By default, it returns 

是的。

if(shouldComponentUpdate) 
     // then render() is called and update UI/view 
else
   // then render() is not called ....[Don't update UI]

【讨论】:

【参考方案5】:

shouldComponentUpdate 方法返回布尔值 指定 React 是否应该继续渲染。

默认值为真。

何时使用 shouldComponentUpdate: 当你希望你的组件在你的前一个状态值等于下一个状态值时不呈现时

【讨论】:

以上是关于即使该组件的道具或状态没有改变,也会调用 React shouldComponentUpdate()的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS 从子组件修改父状态

在不改变状态、道具或父级的情况下反应子级渲染

将状态作为道具传递给子组件不起作用

为啥即使我没有将 vuex 状态绑定到任何 html 输入元素,我的 vuex 状态也会在更改组件级别状态时发生变化?

使用 get API 调用反应全局状态/道具(没有 Redux)

反应孩子正在通过道具改变父母状态......我不清楚原因