Подтвердить что ты не робот

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>
    );
  }
}
4b9b3361

Ответ 1

React алгоритм согласования предполагает, что без какой-либо другой информации, если пользовательский компонент появляется в одном месте на последующих визуализаторах, это тот же компонент, что и раньше, поэтому повторно использует предыдущий экземпляр вместо создания нового.

Если вы должны были реализовать componentWillReceiveProps(nextProps), вы увидите, что вместо этого вызывается вызов.

Различные Node Типы

Очень маловероятно, что элемент <Header> будет генерировать DOM, который будет выглядеть так, как генерирует <Content>. Вместо того чтобы проводить время, пытаясь сопоставить эти две структуры, React просто восстанавливает дерево с нуля.

В качестве следствия, если есть элемент <Header> в том же положении в двух последовательных рендерах, вы ожидаете увидеть очень похожую структуру, и стоит изучить его.

Пользовательские компоненты

Мы решили, что два пользовательских компонента одинаковы. Поскольку компоненты являются сдержанными, мы не можем просто использовать новый компонент и называть его днем. React берет все атрибуты из нового компонента и вызывает component[Will/Did]ReceiveProps() на предыдущем.

Предыдущий компонент теперь работает. Вызывается его метод render() и алгоритм diff перезапускается с новым результатом и предыдущим результатом.

Если вы даете каждому компоненту уникальный key prop, React может использовать изменение key, чтобы сделать вывод, что компонент фактически был заменен и будет создавать новый с нуля, предоставляя ему полный жизненный цикл компонента.


  renderContent() {
    if (this.state.activeItem === 'Item 1') {
      return (
        <Content title="First" key="first" />
      );
    } else {
      return (
        <Content title="Second" key="second" />
      );
    }
  }