> For the complete documentation index, see [llms.txt](https://max-frontend.gitbook.io/react-course-ru-v2/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://max-frontend.gitbook.io/react-course-ru-v2/zhiznennii-tsikl-komponenta.md).

# Жизненный цикл компонента

Любимая фраза этого учебника "давайте представим задачу":

Мы отрисовали компонент, в котором есть input, и хотим чтобы фокус сразу же установился в него. Когда я первый раз подумал "как это сделать", даже не придумал что и ответить.

Хорошо, допустим я знаю, что могу достучаться до DOM элемента через *this.input.current* и вызвать нативный метод `focus()`, но в какой момент стучаться?

Какие вообще "моменты" есть?

## Lifecycle methods

У каждого компонента, есть жизненый цикл (*lifecycle*): компонент будет примонтирован, компонент отрисовался, компонент будет удален и так далее...

У всех этих фаз есть методы, так называемые *lifecycle-methods*. Полный [список](https://reactjs.org/docs/react-component.html#the-component-lifecycle) как всегда в документации. Предлагаю вам в конце урока еще раз его посмотреть, а пока хватит информации и здесь.

*Маленькая ремарка: здесь я перечислю часть самых популярных методов, причем будут и старые методы, так как еще многие их не вычистили. Старые методы будут отмечены биркой \[DEPRECATED]*

Стартуем:

* *componentWillMount* - компонент будет примонтирован. В данный момент у нас нет возможности посмотреть DOM элементы. **\[DEPRECATED]**
* *componentDidMount* - компонент примонтировался. В данный момент у нас есть возможность использовать *refs*, а следовательно это то самое место, где мы хотели бы указать установку фокуса. Так же, таймауты, ajax-запросы и взаимодействие с другими библиотеками стоит обрабатывать **здесь**.

Этот метод подходит для решения нашей задачи:

```jsx
class TestInput extends React.Component {
  constructor(props) {
    super(props)
    this.input = React.createRef()
  }
  componentDidMount() {
    // ставим фокус в input
    this.input.current.focus()
  }
  onBtnClickHandler = () => {
    alert(this.input.current.value)
  }
  render() {
    return (
      <React.Fragment>
          <input
            className='test-input'
            defaultValue=''
            placeholder='введите значение'
            ref={this.input}
          />
        <button onClick={this.onBtnClickHandler}>Показать alert</button>
      </React.Fragment>
    )
  }
}
```

Принцип прежний: мы находим DOM-узел, считываем его свойство / вызываем его нативный метод, в данном случае - вызываем метод [focus()](https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/focus). Обращаться к DOM-элементам напрямую - **очень редкая практика** в React.

* *componentWillReceiveProps* - компонент получает новые *props*. Этод метод не вызывается в момент первого render'a. В официальной документации очень хороший пример, пожалуй скопирую его: **\[DEPRECATED]**

```javascript
componentWillReceiveProps (nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}
```

Обратите внимание: в этот момент, старые *props* доступны как *this.props*, а новые *props* доступны в виде **nextProps** аргумента функции.

Так же, если вы вызываете *setState* внутри этого метода - **не будет** вызван дополнительный *render*.

* *shouldComponentUpdate* - должен ли компонент обновиться? На самом деле, обычно реакт сам отлично разбирается. Но иногда ручное управление позволяет существенно ускорить работу в "узких местах". С этим методом нужно работать очень аккуратно.
* *componentWillUpdate* - вызывается прямо перед *render*, когда новые *props* и *state* получены. В этом методе нельзя вызывать *setState*. **\[DEPRECATED]**
* *componentDidUpdate* - вызывается сразу после *render*. Не вызывается в момент первого render'а компонента.
* *componentWillUnmount* - вызывается перед тем, как компонент будет удален из DOM.

Конечно, в [документации](https://reactjs.org/docs/react-component.html#the-component-lifecycle) все описано намного подробнее. Я рекомендую с ней ознакомиться.

Здесь **хочу заострить внимание**, что чаще всего в старом коде или старых туториалах будет попадаться метод [componentWillReceiveProps](https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops), который Facebook-команда предлагает заменять на [getDerivedStateFromProps](https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops).

**Итого**: главная мысль данного урока: у компонента есть стадии жизни, "в которые можно писать код". Да, пусть я выступаю здесь как "плохой программист", который советует вам писать свои велосипеды на разных стадиях жизни компонента, но именно таким образом вы быстро освоитесь. Ставьте *console.log* и смотрите когда он срабатывает. Думайте как это можно использовать в своих целях.

Если же вы принадлежите к "правильному" типу программистов - пожалуйста, вот [все lifecycle-методы](https://reactjs.org/docs/react-component.html#the-component-lifecycle). Выучите, перечитайте, осознайте - и пишите код без багов ;)

**Итого**: существует несколько lifecycle-методов, благодаря которым мы уже почти перестали "лазить" в DOM, а если и делаем это, то осознанно.

[Исходный код](https://github.com/maxfarseer/react-course-ru-v2/tree/chp10-lifecycle) на данный момент.
