【问题标题】:When shouldComponentUpdate / render is called for child components of updated component更新组件的子组件何时调用 shouldComponentUpdate/render
【发布时间】:2019-02-01 20:35:58
【问题描述】:

在网上阅读了一堆关于shouldComponentUpdaterender 的文章后,我想仔细检查在重新渲染组件(调用render 方法)和调用shouldComponentUpdate 时是否正确。

React 文档(以及数十篇文章说)shouldComponentUpdate 仅在收到新道具或有新状态时调用。但乍一看,PureComponent 似乎也是如此……

为了调查它,我编写了示例应用程序:

  • 父组件

import React, { Component } from 'react';
import './App.css';
import Hello from './Hello';

class App extends Component {

  objWithName = { name: 'World' };

  state = {
    date: Date.now()
  }

  componentDidMount() {
    setInterval(() => {
      this.setState({ date: Date.now() });
    }, 2000);
  }

  render() {
    return (
      <div className="App">
        <p>Rendering timestamp {this.state.date}</p>
        <Hello name={this.objWithName} />
      </div>
    );
  }
}

export default App;
  • 子组件

import React from 'react';
export default class Hello extends React.Component {    
    
    shouldComponentUpdate() {
        console.log('shouldComponentUpdate called');
        return true;
    }

    render() {
        console.log('render called');
        return <p>Hello {this.props.name.name}</p>
    }
}

所以我的第一个问题是:这是完全正确的吗?我的意思是:在上面的代码 sn-ps 中,setInterval 中的父组件调用setState 只是为了触发它的更新,但这种状态在任何地方都没有使用。之后,子组件被重新渲染(render 被调用)和shouldComponentUpdate 被调用,即使他没有任何改变(它没有收到任何新的道具,也没有状态)。我在 React 文档中没有找到对这种行为的任何解释,所以我不确定它是如何工作的。更重要的是,如果该子组件在(仅渲染静态字符串)处没有任何输入道具,它也会被重新渲染。有人能解释一下吗?

所以我的第二个问题是:组件接收到新的 props/state 是什么意思?这是否意味着对象值发生了变化(对于基元来说只是新值,对于对象来说是新引用)?

第三件事:假设应用程序中的父级最顶层组件(例如App.js)发生更改(新道具或新状态),这是否意味着默认情况下所有反应组件当前渲染/安装的(即使是没有任何状态的叶子,也没有改变的道具)会重新渲染?

【问题讨论】:

  • 纯组件意味着无状态组件。除了渲染之外,它不使用任何生命周期方法,而且当您使用 PureComponent 时,您实际上并没有修改状态。它的工作原理与 javascript 中的 Pure 函数完全一样,它只接受 props 并返回 JSX 元素。纯组件通过浅比较在内部完成 shouldComponentUpdate 方法的工作
  • 这是您的第一个问题 --> shouldComponent - 默认情况下,通过在内部返回 true 来调用此方法,因此无论 prop 或 state 是否更改,此方法都会被调用。在您的情况下,它会像内部一样被调用

标签: reactjs


【解决方案1】:
  1. shouldComponentUpdate 只是从 setState 调用,并在返回 true(默认行为)时强制渲染 - 并在不同时更新 DOM。这是设计为具有生命周期/流程的。当shouldComponentUpdate 返回 false 时,您可以避免不必要的、通常代价高昂的渲染处理(以及 DOM 更新)。 PureComponent 只是一个优化的、随时可用的组件,其中定义了 shouldComponentUpdate 以浅层比较 props(通过比较引用)。

React 不关心是否使用了 props/state,而不是使用 observables - 你可以使用 mobx。

  1. 新道具意味着任何改变 - shouldComponentUpdate 有责任仔细检查或深入检查,这取决于您的需要。

  2. 是的,所有子节点都将被更新(强制刷新虚拟 DOM 中的节点状态/视图)。这是快速/优化的过程(在虚拟树上操作),但他们应该使用shouldComponentUpdate 来限制他们的重新渲染(以及最终的 DOM 更新)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-04
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2020-08-08
    相关资源
    最近更新 更多