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

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

Мы отрисовали компонент, в котором есть 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) на данный момент.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://max-frontend.gitbook.io/react-course-ru-v2/zhiznennii-tsikl-komponenta.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
