Жизненный цикл компонента
Любимая фраза этого учебника "давайте представим задачу":
Мы отрисовали компонент, в котором есть input, и хотим чтобы фокус сразу же установился в него. Когда я первый раз подумал "как это сделать", даже не придумал что и ответить.
Хорошо, допустим я знаю, что могу достучаться до DOM элемента через this.input.current и вызвать нативный метод focus(), но в какой момент стучаться?
Какие вообще "моменты" есть?

Lifecycle methods

У каждого компонента, есть жизненый цикл (lifecycle): компонент будет примонтирован, компонент отрисовался, компонент будет удален и так далее...
У всех этих фаз есть методы, так называемые lifecycle-methods. Полный список как всегда в документации. Предлагаю вам в конце урока еще раз его посмотреть, а пока хватит информации и здесь.
Маленькая ремарка: здесь я перечислю часть самых популярных методов, причем будут и старые методы, так как еще многие их не вычистили. Старые методы будут отмечены биркой [DEPRECATED]
Стартуем:
  • componentWillMount - компонент будет примонтирован. В данный момент у нас нет возможности посмотреть DOM элементы. [DEPRECATED]
  • componentDidMount - компонент примонтировался. В данный момент у нас есть возможность использовать refs, а следовательно это то самое место, где мы хотели бы указать установку фокуса. Так же, таймауты, ajax-запросы и взаимодействие с другими библиотеками стоит обрабатывать здесь.
Этот метод подходит для решения нашей задачи:
1
class TestInput extends React.Component {
2
constructor(props) {
3
super(props)
4
this.input = React.createRef()
5
}
6
componentDidMount() {
7
// ставим фокус в input
8
this.input.current.focus()
9
}
10
onBtnClickHandler = () => {
11
alert(this.input.current.value)
12
}
13
render() {
14
return (
15
<React.Fragment>
16
<input
17
className='test-input'
18
defaultValue=''
19
placeholder='введите значение'
20
ref={this.input}
21
/>
22
<button onClick={this.onBtnClickHandler}>Показать alert</button>
23
</React.Fragment>
24
)
25
}
26
}
Copied!
Принцип прежний: мы находим DOM-узел, считываем его свойство / вызываем его нативный метод, в данном случае - вызываем метод focus(). Обращаться к DOM-элементам напрямую - очень редкая практика в React.
  • componentWillReceiveProps - компонент получает новые props. Этод метод не вызывается в момент первого render'a. В официальной документации очень хороший пример, пожалуй скопирую его: [DEPRECATED]
1
componentWillReceiveProps (nextProps) {
2
this.setState({
3
likesIncreasing: nextProps.likeCount > this.props.likeCount
4
});
5
}
Copied!
Обратите внимание: в этот момент, старые props доступны как this.props, а новые props доступны в виде nextProps аргумента функции.
Так же, если вы вызываете setState внутри этого метода - не будет вызван дополнительный render.
  • shouldComponentUpdate - должен ли компонент обновиться? На самом деле, обычно реакт сам отлично разбирается. Но иногда ручное управление позволяет существенно ускорить работу в "узких местах". С этим методом нужно работать очень аккуратно.
  • componentWillUpdate - вызывается прямо перед render, когда новые props и state получены. В этом методе нельзя вызывать setState. [DEPRECATED]
  • componentDidUpdate - вызывается сразу после render. Не вызывается в момент первого render'а компонента.
  • componentWillUnmount - вызывается перед тем, как компонент будет удален из DOM.
Конечно, в документации все описано намного подробнее. Я рекомендую с ней ознакомиться.
Здесь хочу заострить внимание, что чаще всего в старом коде или старых туториалах будет попадаться метод componentWillReceiveProps, который Facebook-команда предлагает заменять на getDerivedStateFromProps.
Итого: главная мысль данного урока: у компонента есть стадии жизни, "в которые можно писать код". Да, пусть я выступаю здесь как "плохой программист", который советует вам писать свои велосипеды на разных стадиях жизни компонента, но именно таким образом вы быстро освоитесь. Ставьте console.log и смотрите когда он срабатывает. Думайте как это можно использовать в своих целях.
Если же вы принадлежите к "правильному" типу программистов - пожалуйста, вот все lifecycle-методы. Выучите, перечитайте, осознайте - и пишите код без багов ;)
Итого: существует несколько lifecycle-методов, благодаря которым мы уже почти перестали "лазить" в DOM, а если и делаем это, то осознанно.
Исходный код на данный момент.
Last modified 1yr ago
Copy link