Как React захватывает реквизит с помощью `const props = this.props`

#javascript #reactjs #closures

#javascript #reactjs #замыкания

Вопрос:

Я прочитал статью, написанную Дэном. В примере ниже

 class ProfilePage extends React.Component {
  showMessage = (user) => {
    alert('Followed '   user);
  };

  handleClick = () => {
    const props = this.props;
    setTimeout(() => this.showMessage(props.user), 3000);
  };

  render() {
    return <button onClick={this.handleClick}>Follow</button>;
  }
}
  

Почему props не изменяется при this.props изменении, поскольку оба указывают на одну и ту же ссылку?

Комментарии:

1. Как вы меняете реквизит user ?

2. @Blundering Philosopher, user изменен в родительском компоненте, но я думаю, что это не связано с этим вопросом, поэтому я оставляю его в стороне.

Ответ №1:

props объект неизменяем, this.props ссылка может меняться со временем в случае получения новых реквизитов.

Это должно быть:

   handleClick = () => {
    setTimeout(() => {
      const { props } = this;
      this.showMessage(props.user);
    }, 3000);
  };
  

Кроме того, следует отслеживать тайм-ауты для отмены при размонтировании компонента, чтобы предотвратить утечки и исключения.

Комментарии:

1. Привет, @estus, спасибо за объяснение. что меня смущает, так это то, что props это просто локальная ценность в методе, как React может сделать его неизменяемым, когда this.props он изменяемый? И как мы можем смоделировать это в простой программе js / ts без React?

2. this.props не подлежит изменению. Это гарантируется Object.freeze в режиме разработки. Каждый раз, когда получены реквизиты, назначается новый объект props, componentInstance.props = Object.freeze({ ... }) . Вы сохранили ссылку на старый объект props с помощью const props = this.props . Вы можете проверить, что это было изменено во время обратного вызова по таймауту, console.log(props !== this.props) .

3. Спасибо, теперь я понимаю, что происходит