reactjs-React:为什么组件的构造函数只被调用一次?

在以下示例中,当单击Item 2时,显示的是Second 1,而不是Second 2。为什么? 您将如何解决?


var guid = 0;

class Content extends React.Component {
  constructor() {
    guid += 1;
    this.id = guid;
    console.log('ctor', this.id); // called only once with 1
  }
  render() {
    return (
      <div className="content">
        {this.props.title} - {this.id}
      </div>
    );
  }
}

class MyApp extends React.Component {
  constructor() {
    this.items = ['Item 1', 'Item 2'];
    this.state = {
      activeItem: this.items[0]
    };
  }
  onItemClick(item) {
    this.setState({
      activeItem: item
    });
  }
  renderMenu() {
    return (
      <div className="menu">
        <div onClick={this.onItemClick.bind(this, 'Item 1')}>Item 1</div>
        <div onClick={this.onItemClick.bind(this, 'Item 2')}>Item 2</div>
      </div>
    );
  }
  renderContent() {
    if (this.state.activeItem === 'Item 1') {
      return (
        <Content title="First" />
      );
    } else {
      return (
        <Content title="Second" />
      );
    }
  }
  render() {
    return (
      <div>
        {this.renderMenu()}
        {this.renderContent()}
      </div>
    );
  }
}
Misha Moroshko asked 2020-02-16T01:18:22Z
1个解决方案
97 votes

React的对帐算法假定没有相反的信息,如果自定义组件出现在后续渲染的同一位置,则它与以前的组件相同,因此将重用前一个实例,而不是创建一个新实例。

如果要实现key,则会看到被调用。

不同的节点类型

key元素不太可能生成看起来像<Content>将生成的DOM。 无需花费时间尝试匹配这两种结构,React只是从头开始重建树。

作为推论,如果在两个连续渲染中的同一位置有key元素,则您会期望看到非常相似的结构,因此值得探索。

定制组件

我们确定两个自定义组件相同。 由于组件是有状态的,因此我们不能仅使用新组件并每天调用它。 React从新组件中获取所有属性,并在前一个组件上调用key

先前的组件现在可以运行了。 调用其2749420355067577577344方法,并使用新结果和先前结果重新启动diff算法。

如果给每个组件一个唯一的key道具,React可以使用key的更改来推断该组件实际上已被替换,并将从头开始创建一个新组件,从而赋予其完整的组件生命周期。


  renderContent() {
    if (this.state.activeItem === 'Item 1') {
      return (
        <Content title="First" key="first" />
      );
    } else {
      return (
        <Content title="Second" key="second" />
      );
    }
  }
Jonny Buchanan answered 2020-02-16T01:19:25Z
translate from https://stackoverflow.com:/questions/29074690/react-why-components-constructor-is-called-only-once