В этой статье мы разберём, что такое в React.js хуки, для чего нужны и какие бывают, думаю вам будет интересно.
Также посмотрите статью: «Быстрый старт на React.js», там вы поймёте как работать с React.js.
Что такое хуки в React.js:
Если кратко говоря, то хуки это элемент в React.js который позволяет работать со состояниями, или другими дынными.
Но использовать их стоит только если вы работаете с функциональным компонентом, а не с классовым, так как в классовом уже всё есть для работы.
FaceBook, (тот кто создал React), рекомендует сейчас использовать функциональные компоненты, то есть те, которые создаются через функцию, а не класс, дело в том что для работы с данными по умолчанию в JS не чего нет, поэтому придумали хуки.
Примечание:
Решение добавить в React.js функциональные компоненты было из-за того, что функции работают быстрее чем классы.
Какие хуки есть в React.js:
Теперь разберём какие хуки бывают в React.js, их достаточно много и они есть для всего.
Основные хуки:
Для начала разберём самые основные хуки, их всего три, useState
, useEffect
и useContext
, разберём их подробнее.
useState:
Самый первый это useState
, и как понятно из названия это хук позволяет работать со состояниями, вот пример создания хука:
1 | const [state, setState] = useState(initialState); |
Таким образом мы создали состояние, state
хранит состояние, setState
это аналог this.setState()
в классовых компонентах, то есть служит для изменения его.
В качестве initialState
может служить всё что угодно, от обычной простой переменной, до массива и объекта, вот пример по сложнее:
1 2 3 4 5 6 7 8 9 10 11 | function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> Счёт: {count} <button onClick={() => setCount(initialCount)}>Сбросить</button> <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button> <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button> </> ); } |
Давайте разберём этот пример, вначале мы создаём состояние, потом возвращаем счётчик в счётчики мы выводим значение и несколько кнопок.
Первая кнопка отвечает за сброс всего состояния, вторя вычитает из счётчика единицу, тут как вы можете заметить используется стрелочная функция, которая в качестве параметра использует prevCount
, которое равно предыдущими значению счётчика, то есть мы убываем из прошлого состояния.
Следующая кнопка аналогичная, только уже прибавляет одно значение и как видите в целом не чего сложного тут нет.
Также у многих может возникнуть вопрос как менять объекты, вот вам не большой пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | const [objects, setObjects] = useState({ title: "Интересный заголовок", time: "20:12", }); const [array, setArray] = useState([1, 2, 3, 4, 5]); setObjects(prev => { return { ...prev, title: "Новый заголовок" } }) setArray(prev => { return { ...prev, [1]: 10 } }) |
Как можете видеть менять объект не так уж и сложно, вам просто нужно возвращать новый объект в который кладёте все предыдущие значение, через ...prev
и меняете любое другое значение по его ключу.
С массивом всё точно также, только если нудно взять ключ, мы его берём в квадратные скобки, хотя с объектом можно делать так же, но только в том случае, если в качестве ключа вы передаёте переменную, в других случаях это не имеет смысла.
useEffect:
Теперь перейдём к useEffect
, с ним всё на много проще, он используется для отслеживания рендеринга, то есть в него мы передаём функцию которая будет срабатывать при новом рендере контента.
1 2 3 | useEffect(() => { console.log("Произошёл рендеринг") }) |
Как видите из не большого примера выше, мы будем выводить в консоль браузера надпись «Произошёл рендеринг».
Но так же вы можете отслеживать рендеринг при изменения конкретного состояния, для этого в useEffect()
принимает второй параметр, который равен массиву состояний которых нужно отслеживать.
1 2 3 | useEffect(() => { console.log("Произошёл рендеринг state") }, [state]) |
Состояние всё так же берётся из useState
, и здесь мы выводим в консоль браузера надпись «Произошёл рендеринг state», но только при изменение состояния state
.
Также эффекты создаёт ресурсы которые нужно отчистить, например, подписки, таймер или событие, вот как можно очистит подписки:
1 2 3 4 5 6 7 | useEffect(() => { const subscription = props.source.subscribe(); return () => { // Очистить подписку subscription.unsubscribe(); }; }); |
Таким же образом можно можно отключить таймер или удалить обработчик события.
useContext:
Теперь осталось разобрать последний важный хук, useContext, как понятно из названия, он нужен для работы с контекстом.
Примечание:
Контекст даёт возможность брать данные компонентам которые находиться ниже от компонента которые находиться выше при этом не используя пропсы.
Давайте покажу вам не большой пример:
1 | const value = useContext(MyContext); |
Тут самое интересное, это значение MyContext
, если кратко говоря, то это контекст, который возвращается от функции React.createContext
, контекст в него передаться в атрибуте value, вот более подробный пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | const themes = { light: { foreground: "#000000", background: "#eeeeee" }, dark: { foreground: "#ffffff", background: "#222222" } }; const ThemeContext = React.createContext(themes.light); function App() { return ( <ThemeContext.Provider value={themes.dark}> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { const theme = useContext(ThemeContext); return ( <button style={{ background: theme.background, color: theme.foreground }}> Я стилизован темой из контекста! </button> ); } |
Как можете заметить в контекст по умолчанию мы передаём объект themes.light
, но уже в value
мы передаём themes.dark
, и как можете заметить, мы контекст используем уже в кнопки, минув Toolbar
, в этом и суть контекста.
Тут я не стал особо много рассказывать про контекст, так как это очень обширная и сложная тема, может в другой раз.
Дополнительные хуки:
Также есть ряд дополнительных хуков о которых я не буду особо много говорить, но их стоит знать, хотя бы для чего каждый нужен.
- useReducer — Аналог
useState
, принимает редюсер со состоянием и действием, возвращает изменённое состояние, если вы работали с Redux, то вам это знакомо; - useCallback — Возвращает мемоизированный колбэк, в качестве параметров принимает в себя встроенный колбэк и массив зависимостей;
- useMemo — Тоже самое что и
useCallback
, но уже возвращает значение; - useRef — Возвращает изменяемый ref-объект, в целом
useRef
похож на useState, только без функции для изменения и доступ к объекту происходить через свойство.current
; - useImperativeHandle — настраивает значение экземпляра, которое предоставляется родительским компонентам при использовании
ref
; - useLayoutEffect — Аналог
useEffect
, но запускается уже синхронно после всех изменений DOM; - useDebugValue — может использоваться для отображения метки для пользовательских хуков в React DevTools;
Как видите их ещё много, но в целом с ними работать примерно также как и с первыми тремя, разницы особо нет.
Вывод:
В этой статье вы прочитаете прочитали про хуки в React.js, тут объяснили что это такое и как используется, думаю вам было интересно.