Каковы гарантии на порядок событий жизненного цикла React между компонентами? - PullRequest
0 голосов
/ 27 сентября 2019

Каковы гарантии в отношении порядка жизненного цикла React для отдельных компонентов и четко ли они документированы в любом месте?

Например, если у меня есть:

<div>{ x ? <A /> : <B /> }</div>

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

Существуют ли гарантии относительно порядка, в котором события жизненного цикла, связанные с монтированием, будут запускаться между этими элементами?

Например, хорошо задокументировано , что render для A сработает до componentDidMount для A, когда x изменится на true.Тем не менее, гарантируется ли, что componentWillMount для A сработает после componentDidUnmount для B?

Для дальнейшего продвижения: изменится ли это, если A и B являются дочерними элементами ниже в этом дереве, с переключателем внаверх?

Любые ответы приветствуются, но твердую документацию по этому поводу очень ценят.

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

componentDidUnmount никогда не вызывается при условном рендеринге.

Я протестировал на codepen и получил результат, как показано ниже:

Родительский компонент

  constructor(props) {
    super(props);
    this.state = {
      flag: false,
    }
  }
  render() {
    const { flag } = this.state;
    return (
      <div>
        <h2 onClick={() => this.setState({flag: !flag})}>CONVERT</h2>
        <div>
          { flag ? <A /> : <B /> }
        </div>
      </div>
    );
  }

Дочерний компонент A


class A extends React.Component {
  componentDidMount() {
    console.log('A is mounted');
  }
  componentWillMount() {
    console.log('A will be mounted');
  }
  componentWillUnmount() {
    console.log('A will be unmounted');
  }
  componentDidUnmount() {
    console.log('A is unmounted');
  }
  render() {
    return (
      <h1>A</h1>
    );
  }
}

Дочерний компонент B

Almost the same as A :D

Результат

Я дважды щелкнул CONVERT, и результат был:

"B will be mounted"  // first render
"B is mounted"

"B will be unmounted" // first click
"A will be mounted"
"A is mounted"

"A will be unmounted" // second click
"B will be mounted"
"B is mounted"

componentDidUnmount никогда не вызывался при условном рендеринге.

0 голосов
/ 30 сентября 2019

Иногда мне было трудно понять фундаментальные различия между методами componentWillMount () и componentDidMount ().Я продолжал разочаровываться, когда кто-то работал, но я не понимал, как и почему.

componentWillMount () Одна большая загвоздка, которую я не осознавал до сессии онлайн-исследовательской группы, состоит в том, что componentWillMount () устарелв 2018. Хотя вы можете продолжать использовать его (до React 17.0), это не лучшая практика, потому что это небезопасно для асинхронного рендеринга.Если вы решите продолжать использовать его, вы должны использовать UNSAFE_componentWillMount ().

Причина Использование вызова выборки в componentWillMount () заставляет компонент сначала визуализироваться с пустыми данными, потому что componentWillMount () НЕ будетвозврат до первого рендеринга компонента.

Из-за того, что события JavaScript являются асинхронными, при выполнении вызова API браузер продолжает выполнять другую работу, пока вызов все еще находится в движении.С React, в то время как компонент выполняет рендеринг, он не ожидает завершения componentWillMount (), поэтому компонент продолжает рендеринг.

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

Когда я строил свой проект, я не знал об устаревании componentWillMount (), и я не сделалНе понимаю, почему я продолжал получать сообщение об ошибке «не могу прочитать свойство« карта »из неопределенного».Я был в замешательстве, потому что у меня был массив, и он должен был заполняться данными, но это не так.

Оказывается, это имеет смысл, так как компонент сначала отображается с пустыми данными, поэтомумассив был пуст и не мог быть повторен.Только в этот момент я узнал, что рекомендуется использовать componentDidMount ().

componentDidMount () Лучшее место для вызовов для извлечения данных - в componentDidMount ().componentDidMount () вызывается только один раз на клиенте по сравнению с componentWillMount (), который вызывается дважды, один раз на сервер и один раз на клиенте.Он вызывается после первоначального рендеринга, когда клиент получил данные с сервера, и до того, как данные отображаются в браузере.В связи с тем, что данные не будут загружены до тех пор, пока после первоначального рендеринга, разработчику НЕОБХОДИМО правильно настроить начальное состояние компонентов.

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

...