何时应为更新后的组件的子组件调用shouldComponentUpdate / render

时间:2018-08-27 10:12:11

标签: reactjs

在网络上已经阅读了大量关于shouldComponentUpdaterender的文章,我想仔细检查在重新渲染组件(调用render方法)以及何时重新获得正确的内容。 shouldComponentUpdate被调用。

仅在收到新道具或有新状态的情况下,对文档(以及数十篇文章说)进行反应( 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>
    }
}

所以我的第一个问题是:这是真的吗?我的意思是:在以上代码段中,setInterval中的父组件只是为了触发其更新而调用setState,但是此状态在任何地方都没有使用。然后,子组件被重新渲染(称为render)和shouldComponentUpdate被调用,即使他没有任何改变(它没有收到任何新道具,也没有陈述)。我没有在React docs中找到对此行为的任何解释,所以我不确定它是如何工作的。而且,如果该子组件在(简单地渲染静态字符串)处没有任何输入道具,它也将被重新渲染。 sb可以解释吗?

第二个问题是:该组件接收到新的道具/状态是什么意思?这是否意味着对象值已更改(对于基元而言,只是新值,而对于对象而言,则是新引用)?

第三件事:假设应用程序中父级最主要的组件(例如App.js)发生了更改(新属性或新状态),这是否意味着默认情况下,ALL做出反应当前渲染/安装的组件(甚至没有任何状态的叶子,也没有更改的道具)都将重新渲染?

1 个答案:

答案 0 :(得分:0)

    只是从shouldComponentUpdate中调用
  1. setState,并在返回true(默认行为)时强制渲染(默认行为),并在不同时更新DOM。这是设计使然具有生命周期/流程。当shouldComponentUpdate返回false时,可以避免不必要的,通常是昂贵的渲染处理(和DOM更新)。 PureComponent只是经过优化的,随时可用的,定义为shouldComponentUpdate的组件,用于通过比较引用浅浅比较道具。

React不在乎是否使用道具/状态,而不是使用可观察对象-您可以使用mobx。

  1. 新道具意味着任何改变-根据您的需要,吞咽或深入检查是shouldComponentUpdate的责任。

  2. 是的,将更新所有子级(强制刷新虚拟DOM中的节点状态/视图)。这是一个快速/优化的过程(在虚拟树上运行),但是他们应该使用shouldComponentUpdate来限制其重新呈现(以及最终的DOM更新)。