为什么从父组件调用子组件componentDidUpdate的setState?

时间:2018-08-17 11:14:15

标签: reactjs

在此示例中,当我设置状态跟踪时触发了componentDidUpdate。 HelloMessage的道具和状态未更改,所以为什么要调用此方法?如何预防呢?

class HelloMessage extends React.Component {
  componentDidUpdate(prevProps, prevState) {
    console.log('HelloMessage did update');
  }

  render() {
    return <div>Hellooo</div>;
  }
}

class App extends React.Component {
  state = { trail: null }

  componentDidMount() {
    this.setState({ trail: 'First' });    
  }

  render() {
    return (
      <div>
        <HelloMessage />
        <div>
          {this.state.trail}
        </div>
      </div>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('container')
);

5 个答案:

答案 0 :(得分:2)

由于HelloMessage没有获得任何道具,因此可以扩展React.PureComponent。您将获得与使用shouldComponentUpdate返回false相同的结果。

答案 1 :(得分:1)

这是预期的行为。只要父组件的状态发生变化,该组件就会被重新渲染。和您所有的组件逻辑,即。子组件也存在于render方法中。因此,子组件将再次呈现。

如果您不想更新,则需要显式返回react的shouldComponentUpdate挂钩。

shouldComponentUpdate(nextProps, nextState) {
    return nextState
}

由于子组件的nextState仍然为null,因此componentUpdate将返回null。这表明不更新组件。这样,仅当子状态更改时,子组件才能重新呈现。

答案 2 :(得分:0)

它将调用componentDidUpdate,因为调用了父组件的render方法。您可以检查道具是否已更改,然后执行代码。

答案 3 :(得分:0)

componentDidMount() {
  this.setState({ trail: 'First' });    
}

此状态更改将调用重新渲染应用程序,这将触发子 HelloMessage 组件的更新。为避免这种情况,请在 HelloMessage 中使用shouldComponentUpdate(nextProps, nextState),然后将nextProps与当前的prop进行比较,以决定是否更新组件。

答案 4 :(得分:0)

我相信背后的逻辑是这样的:

如果组件的属性或状态发生变化,则它将触发重新渲染。这也意味着它将重新渲染其子级(依此类推)。现在,即使子级中的道具/状态没有改变,它仍将触发重新渲染,因为shouldComponentUpdate()默认情况下始终返回true。因此,如果您不希望孩子重新渲染,即使它的父母重新渲染,也可以添加:

shouldComponentUpdate() {
    return false;
}

这样它就不会更新(很明显,您可以在该生命周期方法中添加检查,以决定是否进行更新,以后是否应该添加道具等)。