Жизненный цикл компонентов и хуки
Изначально в библиотеке React использовались, в основном, компоненты, основанные на классах. Применение таких компонентов может потребовать приложения чрезмерных усилий в ходе разработки, так как программисту постоянно приходится переключаться между классами, компонентами высшего порядка, свойствами рендеринга. А с появлением хуков React можно, решая те же задачи, что и раньше, не переключаясь между различными механизмами, просто пользоваться функциональными компонентами. Хуки значительно улучшили React из-за того, что с их помощью можно писать код, который получается проще, чем код, который писали раньше, но при этом позволяет быстрее и эффективнее реализовывать похожий функционал. А ещё можно, не пользуясь классами, работать с состоянием компонентов и с методами их жизненного цикла. Вот примеры кода, иллюстрирующие использование компонентов, основанных на классах, и функциональных компонентов. Компонент, основанный на классах:
import React, { Component } from 'react'
export default class Hello extends Component {
render() {
return(
<div>
Hello World!
</div>
)
}
Этот компонент выводит в DOM элемент <div>
с сообщением Hello World!
.
А вот — код функционального компонента, решающего ту же задачу.
import React from 'react'
export default function Hello() {
return (
<div>
Hello World!
</div>
)
}
Сравнение этих двух примеров показывает, что код функционального компонента гораздо проще кода аналогичного компонента, основанного на классах. Для его использования не нужно создавать экземпляр класса, не нужно вызывать render()
. Достаточно просто вызвать нужную функцию. Хуки React обладают многими достоинствами, они способны помочь программисту в решении множества задач. Одна из главнейших сильных сторон хуков заключается в том, что они упрощают работу с методами жизненного цикла компонентов React.
Да, обратите внимание на то, что хуки нельзя использовать в компонентах, основанных на классах.
Как хуки упрощают работу с методами жизненного цикла компонентов?
Среди методов жизненного цикла React-компонента можно отметить те, которые вызываются при его монтировании, обновлении и размонтировании.
Монтирование — это вставка элементов в DOM.
Обновление — это, как можно судить по названию, обновление элементов DOM.
Размонтирование — это удаление элементов из DOM.
Вот схема, на которой представлены различные методы жизненного цикла React-компонента.
Методы жизненного цикла React-компонента
Изначально эти методы можно было использовать только при применении компонентов, основанных на классах. Это обычно было связано с необходимостью работать с кодом, который достаточно сложно писать и читать. Если же пользоваться функциональными компонентами и хуками — решение тех же задач упрощается.
Предположим, нам нужно загрузить данные с использованием метода жизненного цикла componentDidMount()
в компоненте, основанном на классах:
import React, { Component } from 'react'
import Axios from 'axios'
export default class Hello extends Component {
constructor(props) {
super(props);
this.state = { name: ""};
}
componentDidMount() {
Axios.get('/api/user/name')
.then(response => {
this.setState({ name: response.data.name })
})
}
render() {
return (
<div>
My name is {this.state.name}
</div>
)
}
}
А теперь решим ту же задачу в функциональном компоненте, пользуясь хуками useState
и useEffect
:
import React, { useEffect, useState } from 'react'
import Axios from 'axios'
export default function Hello() {
const [Name, setName] = useState("")
useEffect(() => {
Axios.get('/api/user/name')
.then(response => {
setName(response.data,name)
})
}, [])
return (
<div>
My name is {Name}
</div>
)
}
Этот код загружает нужные данные с использованием Axios API и выводит их в DOM. Хуки useEffect
и useState
позволяют писать более эффективный и компактный код, чем код, который пишут при использовании компонентов, основанных на классах. Такой код получается понятнее, с ним легче работать. При использовании методов жизненного цикла в компонентах, основанных на классах, приходится по-отдельности работать с методами componentDidMount()
, componentDidUpdate()
, componentWillUnmount()
, а при использовании хуков можно просто сделать всё, что нужно, с помощью useEffect
.
Хуки облегчили изучение React
Компоненты, основанные на классах, всегда были несколько громоздкими и непонятными конструкциями, особенно учитывая то, что их применение ведёт к тому, что механизмы управления состоянием компонента и многократного использования кода кажутся сложнее, чем они есть на самом деле. Это привело к тому, что многие новички избегали React, выбирая более «лёгкие» библиотеки и фреймворки. А с появлением хуков изучить React стало легче, чем прежде. Это стало одной из причин роста популярности React.
Вопросы о различных библиотеках и фреймворках на Stack Overflow На этом графике виден постоянный рост интереса к React на Stack Overflow, продолжающийся уже много лет. Здесь же можно сравнить процент вопросов о React с процентом вопросов о других популярных JavaScript-инструментах. Этот график доказывает то, что разработчики стали чаще пользоваться библиотекой React после появления хуков.
О некоторых хуках и их предназначении
До появления хуков организация кода компонентов на основе методов жизненного цикла вынуждала разработчиков «разбрасывать» по разным компонентам код, направленный на реализацию схожей логики. Для решений этой и других мелких проблем в React были введены функциональные компоненты, что позволило упростить код и сделать его более гибким. Ещё одна задача, которую постоянно приходилось решать разработчикам с использованием не особенно удобных механизмов, заключалась в изменении состояния компонентов. Для решения этой задачи теперь используется хук useState
.
▍Хук useState
Вероятно, useState
— это самый распространённый React-хук. Он позволяет работать с переменными состояния в функциональных компонентах.
const loadingTuple = React.useState(true)
const loading = loadingTuple[0]
const setLoading = loadingTuple[1]
loading // true
setLoading(false)
loading // false
Здесь useState
принимает единственный аргумент: исходное значение состояния. Он возвращает массив с переменной state
и с функцией для обновления этого состояния. После этого у программиста есть всё, что нужно для работы с состоянием в функциональном компоненте.
Следующий хук, который мы рассмотрим, направлен на работу с методами жизненного цикла в функциональных компонентах. Он называется useEffect
.
▍Хук useEffect
Хук useEffect
помогает программисту выполнять побочные эффекты в функциональных компонентах. То есть — вызывать функции, которые нужно выполнить после обновления DOM. Он заменяет некоторые события, позволяя вызывать функцию при изменении одной или нескольких переменных. Он принимает два аргумента: функцию и необязательный массив. Эта функция определяет то, какой именно «побочный эффект» нужно выполнить, а в массиве указывают переменные, за изменениями которых нужно наблюдать.
▍Другие хуки
useContext
: позволяет работать с контекстом — с механизмом, используемым для организации совместного доступа к данным без необходимости передачи свойств.useRef
: позволяет напрямую обращаться к DOM в функциональных компонентах. Обратите внимание на то, чтоuseRef
, в отличие отsetState
, не вызывает повторный рендеринг компонента.useReducer
: хранит текущее значение состояния. Его можно сравнить с Redux.useMemo
: используется для возврата мемоизированного значения. Может применяться в случаях, когда нужно, чтобы функция возвратила бы кешированное значение.useCallback
: применяется в ситуациях, когда дочерние элементы компонента подвергаются постоянному повторному рендерингу. Он возвращает мемоизированную версию коллбэка, которая меняется лишь тогда, когда меняется одна из зависимостей.
Итоги
Мы, при создании React-компонентов, пользовались классами из-за того, что в своё время для работы с состоянием или для реализации методов жизненного цикла нельзя было воспользоваться функциональными компонентами. Хуки React значительно упростили решение старых задач, дав нам возможность писать код, который отличается лучшей пригодностью к созданию нового функционала методом композиции, который получается гибче, чем прежде, который легче расширять. Многие компании используют React в роли своей основной фронтенд-библиотеки, что приводит к тому, что всё больше и больше разработчиков осваивают React.
Last updated