Що таке хук у Реакті

Що таке хук у Реакті



Огляд хуків¶

Хукі дозволяють використовувати різні функції React з ваших компонентів. Ви можете використовувати вбудовані хуки або комбінувати їх для створення власних. На цій сторінці наведено всі вбудовані хуки в React.

Хуки стану¶

Стан дозволяє компоненту "запам'ятовувати" інформацію, наприклад, що вводиться користувачем. Наприклад, компонент форми може використовувати стан зберігання значення введення, а компонент галереї зображень - для зберігання індексу вибраного зображення.

Щоб додати стан до компонента, використовуйте один із цих хуків:

  • useState оголошує змінну стану, яку можна оновлювати безпосередньо.
  • useReducer оголошує змінну стану з логікою оновлення всередині функції reducer.

Контекстні хуки¶

Контекст дозволяє компоненту отримувати інформацію від віддалених батьків, не передаючи її як пропсів. Наприклад, компонент верхнього рівня вашої програми може передавати поточну тему інтерфейсу користувача всім компонентам нижче, незалежно від глибини.

Реф хукі¶

Рефи дозволяють компоненту зберігати деяку інформацію, яка не використовується для рендерингу, наприклад, вузол DOM або ідентифікатор таймауту. На відміну від стану оновлення рефа не призводить до повторного рендерингу компонента. Рефи - це "аварійний люк" із парадигми React. Вони корисні, коли вам потрібно працювати з системами, що не належать до React, наприклад, із вбудованими API браузера.

  • useRef оголошує реф. Ви можете зберігати в ньому будь-яке значення, але найчастіше використовується для зберігання вузла DOM.
  • useImperativeHandle дозволяє вам налаштувати реф, що відкривається вашим компонентом. Це рідко використовується.

Хуки ефектів¶

Ефекти дозволяють компоненту підключатися до зовнішніх систем та синхронізуватися з ними Це включає роботу з мережею, DOM браузера, анімацією, віджетами, написаними з використанням іншої бібліотеки UI, та іншим не-React кодом.

Ефекти – це "аварійний люк" з парадигми React. Не використовуйте ефекти для оркестрування потоку даних у вашому додатку. Якщо ви не взаємодієте із зовнішньою системою, можливо, вам не потрібен ефект.

Існують дві рідко використовувані варіанти використанняефекту з відмінностями в часі:

  • useLayoutEffect спрацьовує до того, як браузер перемальовує екран. Ви можете виміряти компонування тут.
  • useInsertionEffect спрацьовує до того, як React вносить зміни до DOM. Тут бібліотеки можуть вставляти динамічні CSS.

Хуки продуктивності¶

Загальний спосіб оптимізації продуктивності повторного рендерингу – пропустити непотрібну роботу. Наприклад, ви можете вказати React повторно використовувати кешовані обчислення або пропустити повторний рендеринг, якщо дані не змінилися з попереднього рендерингу.

Щоб пропустити обчислення та непотрібний повторний рендеринг, використовуйте один із цих хуків:

  • useMemo дозволяє кешувати результат дорогого обчислення.
  • useCallback дозволяє кешувати визначення функції перед передачею її оптимізованим компонентом.

Іноді не можна пропустити повторний рендеринг, тому що екран має дійсно оновлюватися. У цьому випадку можна підвищити продуктивність, відокремивши блокуючі оновлення, які повинні бути синхронними (наприклад, введення даних у поле введення), від неблокуючих оновлень, які не повинні блокувати інтерфейс користувача (наприклад, оновлення графіка).

Щоб встановити пріоритет рендерингу, використовуйте один із цих хуків:

  • useTransition дозволяє позначити перехід стану як неблокуючий і дозволити іншим оновленням переривати його.
  • useDeferredValue дозволяє відкласти оновлення некритичної частини інтерфейсу користувача і дозволити іншим частинам оновлюватися першими.

Хуки ресурсів¶

Компонент може отримати доступ до ресурсів, не маючи їх як частину свого стану. Наприклад, компонент може прочитати повідомлення з Promise або прочитати інформацію про стиль із контексту.

Щоб прочитати значення з ресурсу, використовуйте цей хук:

Інші хуки¶

Ці хуки переважно корисні авторам бібліотек і не часто використовуються в коді програми.

  • useDebugValue дозволяє вам налаштувати мітку, яку React DevTools відображає для вашого хука користувача.
  • useId дозволяє компоненту зв'язати із собою унікальний ID. Зазвичай використовується в API доступності.
  • useSyncExternalStore дозволяє компоненту підписатися на зовнішній магазин.

Введення в хуки

Хукі — нововведення у React 16.8, що дозволяє використовувати стан та інші можливості React без написання класів.

import React,
 useState  >
from
'react';
function
Example()

// Оголошення змінної стану, яку ми назвемо " count "
const
[count, setCount]
=
useState(0);
return
(
div>
p>Ви клікнули
count>
разp>
button
onClick=()
=>
setCount(count  +
1)>>
Натисни на мене
button>
div>
);
>

Перший хук, який ми вивчимо, це функція використаннядержави. Не турбуйтеся, якщо цей приклад буде спочатку незрозумілий. Скоро ми розберемося, як він працює.

Ви можете почати вивчати хуки на наступній сторінці. Тут ми розповімо, навіщо ми додали хуки в React, і як вони допоможуть вам писати програми.

Примітка

React 16.8.0 – це перший реліз, що підтримує хуки.При оновленні версії, не забудьте оновити всі залежності, включаючи React DOM. Підтримка хуків React Native з'явилася у версії 0.59.

На конференції React Conf 2018, Софі Алперт (Sophie Alpert) та Ден Абрамов (Dan Abramov) представили хуки, а Райн Флоренс (Ryan Florence) показав, як їх використовувати у додатку. Відео конференції можна переглянути тут:

Повна зворотна сумісність

Перед тим, як ми продовжимо, зверніть увагу, що хуки:

  • Цілком на ваш розсуд. Можна спробувати хуки в одних компонентах, не змінюючи код в інших. Хуки не обов'язково використовувати чи вивчати прямо зараз.
  • 100% обернено сумісні. Хуки не містять змін, які можуть зламати ваш існуючий код.
  • Доступні зараз. Хуки доступні із виходом версії 16.8.0.

Ми не плануємо видаляти класи з React. Ви можете прочитати більше про стратегію поступового впровадження хуків у розділі нижче.

Хуки не змінюють ваші знання про концепції React. Натомість, хуки надають більш прямий доступ до API вже знайомих вам понять: пропсів, стану, контексту, рефів та життєвого циклу. Ми також розглянемо потужний спосіб компонувати ці поняття за допомогою хуків.

Щоб розпочати вивчати хуки, перейдіть на наступну сторінку! На цій сторінці ми розповімо про те, навіщо потрібні хуки, та як їх використовувати, не переписуючи наші програми.

Хуки вирішують безліч, здавалося б, незв'язаних між собою проблем у React, з якими ми стикалися протягом п'яти років написання та підтримки десятків тисяч компонентів. Якщо ви вивчаєте React, використовуєте його щодня або використовуєте іншу бібліотеку з таким компонентним підходом, ці проблеми напевно здадуться вам знайомими.

Важко повторно використати логіку станів між компонентами

У React немає способу «приєднати» повторно використовувану поведінку до компоненту (наприклад, підключення до сховища). Якщо ви працювали з React якийсь час, то вам можуть бути знайомі такі патерни, як рендер-пропси та компоненти вищого ладу, які намагаються вирішити цю проблему. Але ці патерни змушують вас змінювати структуру компонентів, що робить код громіздким та важким у підтримці. Якщо ви подивіться на типовий React-додаток у React DevTools, то побачите «пекло обгорток» з компонентів, оточених провайдерами, консьюмерами, компонентами вищого порядку, рендер-пропсами та іншими абстракціями. Хоч ми і можемо відфільтрувати їх у DevTools, все це вказує на глибшу проблему React. Потрібен зручніший спосіб повторно використовувати логіку навколо стану.

За допомогою хуків ви можете отримати логіку стану з компонента, щоб її протестувати або повторно використовувати. Хуки дозволяють повторно використовувати логіку стану, не торкаючись дерева компонентів. Завдяки цьому хуки легко використовувати в різних компонентах і ділитися ними з спільнотою.

Ми обговоримо це докладніше у розділі Створення власних хуків.

Складні компоненти стають важкими для розуміння

Нам часто доводилося підтримувати компоненти, які спочатку були простими, але перетворилися на некерований безлад, що складається з логіки стану та побічних ефектів. Кожен метод життєвого циклу часто містить суміш незв'язаної логіки.Наприклад, компоненти можуть завантажувати дані в componentDidMount і componentDidUpdate . метод. Це легко призводить до баг і невідповідностей у додатку.

У деяких випадках неможливо розбити компоненти на більш дрібні, тому що логіка стану розкидана всюди. Такі компоненти складно тестувати. різними файлами та ускладнює повторне використання компонентів.

Щоб вирішити цю проблему, хуки дозволяють розбити один компонент на маленькі функції за призначенням (наприклад, підписці чи завантаженні даних), а не на основі методів життєвого циклу. Ви також можете контролювати внутрішній стан за допомогою редюсера, щоб поведінка була більш передбачуваною.

Класи плутають як людей, так і машини

До того ж ускладнення організації коду та його повторного використання, класи створюють суттєвий бар'єр у вивченні React. код стає багатослівним. Люди можуть чудово розуміти пропси, стан та односпрямований потік даних, але все одно плутатися із класами.Відмінності між функціональними і класовими компонентами React і тим, коли їх використовувати, призводять до розбіжностей навіть між досвідченими React-розробниками.

До того ж, React існує вже близько п'яти років і ми хочемо переконатися, що він залишиться актуальним протягом наступних п'яти років. Як показують Svelte, Angular, Glimmer та інші технології, компіляція компонентів перед їх виконанням має величезний потенціал у майбутньому. Особливо якщо шаблони не накладають обмежень. Нещодавно ми експериментували зі згортанням компонентів з використанням Prepack і побачили перші перспективні результати. Однак ми помітили, що класові компоненти можуть призводити до ненавмисних патернів, які зводять оптимізацію нанівець. Класи створюють складнощі для інструментів і сьогодні. Наприклад, класи погано мініфікуються, а гаряче перезавантаження (hot reloading) ненадійне і часто ламає їх. Наша мета – надати API, який підвищить ймовірність того, що код можна буде оптимізувати.

Щоб вирішити ці проблеми, Хуки дозволяють використовувати більше можливостей React без написання класів. Концептуально, React-компоненти завжди були ближчими до функцій. Хуки забезпечують доступ до функціоналу, але знецінюють досвід використання React. Хуки надають імперативні лазівки і вимагають від вас вивчення складних функціональних чи реактивних підходів.

Стратегія поступового впровадження

TLDR: Ми не плануємо видаляти класи з React.

Ми знаємо, що React-розробники сфокусовані на поставці продукту і не мають часу вивчати новий API кожного релізу. Хуки це щось нове, і, можливо, краще почекати більше прикладів і уроків, перш ніж починати їх вивчення.

Ми також розуміємо, що планка для додавання нових примітивів у React є дуже високою.Тому для цікавих читачів ми підготували докладний RFC, в якому можна знайти більше інформації про технічні аспекти вибраного дизайну.

Важливо розуміти, що хуки працюють поруч із існуючим кодом, тому ви можете впроваджувати їх поступово. Немає поспіху переходити на хуки. Ми рекомендуємо уникати будь-яких великих переписувань, особливо для існуючих, складних класових компонентів. Вам потрібно буде трохи змінити світогляд, щоб почати «мислити хуками». На наш досвід, найкраще спочатку попрактикуватися використовувати хуки в нових і некритичних компонентах і переконатися, що всі у вашій команді почуваються комфортно з ними. Після того, як ви спробуєте, не соромтеся надіслати нам свій відгук, позитивний чи негативний.

Ми маємо намір охопити всі можливі варіанти використання класів у хуках, але ми все ще підтримуватимемо класові компоненти в найближчому майбутньому. У Facebook десятки тисяч компонентів, написаних у вигляді класів, і у нас немає жодних планів їх переписувати. Натомість ми починаємо використовувати хуки в новому коді паралельно з класами.

Часті питання

Ми підготували для вас сторінку FAQ з відповідями на найчастіші питання про хуки.

До кінця цієї сторінки ви повинні мати загальне уявлення про те, які проблеми вирішують хуки, але багато деталей, можливо, залишилися незрозумілими. Не турбуйтесь! Давайте перейдемо на наступну сторінку, де вивчимо хуки на прикладах.

Короткий огляд хуків

Хукі — нововведення у React 16.8, що дозволяє використовувати стан та інші можливості React без написання класів.

Хуки – назад сумісні. На цій сторінці ви отримаєте загальне уявлення про хуки. Майте на увазі, що це огляд, який більше підійде досвідченим користувачам React.Наприкінці кожного розділу є такий жовтий блок з детальним поясненням на випадок, якщо ви заплуталися:

Докладне пояснення

Якщо ви хочете зрозуміти, чому ми додаємо хуки React, прочитайте мотивацію.

Розглянемо приклад, у якому рендерується лічильник. Якщо ви натиснете кнопку, значення лічильника буде інкрементовано.

import React,
 useState  >
from
'react';
function
Example()

// Оголошуємо нову змінну стану " count "
const
[count, setCount]
=
useState(0);
return
(
div>
p>Ви натиснули
count>
разp>
button
onClick=()
=>
setCount(count  +
1)>>
Натисни на мене
button>
div>
);
>

У цьому прикладі useState — це хук (Визначення хука дано нижче). Ми викликаємо його, щоб наділити наш функціональний компонент внутрішнім станом. React зберігатиме цей стан між рендерами. Виклик використаннядержав повертає масив з двома елементами, що містить: поточний значення стану та функцію для його оновлення. Цю функцію можна використовувати будь-де, наприклад, в обробнику подій. Вона схожа з this.setState в класах, але не зливає новий і старий стан разом. Порівняння хука useState і this.state наводиться на сторінці Використання хука стану.

Єдиний аргумент використаннядержави - це початковий стан. У прикладі вище - це 0, так як наш лічильник починається з нуля. Зауважте, що на відміну від this.state , у разі стан може, але з повинно, бути об'єктом. Вихідне значення аргументу використовується лише за першого рендері.

Оголошення кількох змінних стану

Хук стану можна використовувати у компоненті більше одного разу.

function
ExampleWithManyStates()

// Оголошуємо кілька змінних станів!
const
[age, setAge]
=
useState(42);
const
[fruit, setFruit]
=
useState('банан');
const
[todos, setTodos]
=
useState([
text:
'Вивчити хуки'
>]);
// .
>

Синтаксис деструктуризації масивів дозволяє нам по-різному називати змінні стани, які ми оголошуємо при виклику використаннядержав. Так як імен цих змінних немає в API useState, React припускає, що якщо ви викликаєте useState багато разів, ви робите це в однаковій послідовності при кожному рендері. Ми розповімо, чому це працює і коли це доцільно, трохи згодом.

Хуки – це функції, за допомогою яких ви можете «підчепитися» до стану та методів життєвого циклу React із функціональних компонентів. Хуки не працюють усередині класів — вони дають можливість використовувати React без класів. (Ми не рекомендуємо відразу ж переписувати існуючі компоненти, але за бажання ви можете почати використовувати хуки у своїх нових компонентах.)

React містить кілька вбудованих хуків, таких як useState. Ви також можете створювати власні хуки, щоб повторно використовувати їх в інших компонентах. Давайте спочатку розглянемо вбудовані хуки.

Вам, швидше за все, доводилося раніше запитувати дані, робити підписки або вручну міняти DOM з React-компонента. Ми розцінюємо ці операції як «побічні ефекти» (або скорочено «ефекти»), оскільки вони можуть впливати на роботу інших компонентів і не можна їх виконати під час рендеру.

За допомогою хука ефекту useEffect можна виконувати побічні ефекти з функціонального компонента. Він виконує ту ж роль, що і componentDidMount , componentDidUpdate і componentWillUnmount у React-класах, об'єднавши їх у єдиний API. Ви можете знайти порівняння useEffect і цих методів на сторінці використання ефекту хука.

Наприклад, цей компонент встановлює заголовок документа після того, як React оновлює DOM:

import React,
 useState, useEffect  >
from
'react';
function
Example()

const
[count, setCount]
=
useState(0);
// За принципом componentDidMount та componentDidUpdate:
useEffect(()
=>

// Оновлюємо заголовок документа за допомогою API браузера
document.title  =
`Ви натиснули
$count>
раз`;
>);
return
(
div>
p>Ви натиснули
count>
разp>
button
onClick=()
=>
setCount(count  +
1)>>
Натисни на мене
button>
div>
);
>

Коли ви викликаєте useEffect , React отримує вказівку запустити вашу функцію з ефектом після того, як він відправив зміни в DOM. Оскільки ефекти оголошуються всередині компонента, вони мають доступом до його пропсів і стану. За замовчуванням React запускає ефекти після кожного рендеру, включаючи перший рендер. Ми розглянемо докладніше, як це відрізняється від класових методів життєвого циклу на сторінці використання ефекту хука.

При необхідності ви можете повернути з ефекту функцію, яка вказує на ефект, як виконати за собою «скидання». Наприклад, цей компонент використовує ефект, щоб передплатити статус друга в мережі, і виконує скидання, відписуючись від нього.

import React,
 useState, useEffect  >
from
'react';
function
FriendStatus(props)

const
[isOnline, setIsOnline]
=
useState(null);
function
handleStatusChange(status)

setIsOnline(status.isOnline);
>
useEffect(()
=>

ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return
()
=>

ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
>;
>);
if
(isOnline  ===
null)

return
'Завантаження. ';
>
return isOnline  ?
'У мережі'
:
'Не в мережі';
>

У цьому прикладі React буде відписуватися від нашого ChatAPI перед тим, як компонент розмонтується і перед тим, як перезапустити ефект при повторному рендері. Ви можете зробити так, щоб React пропускав повторні підписки, якщо props.friend.id , який ми передали в ChatAPI , залишився без змін.

Як і useState , можна використовувати більше ефекту в компоненті:

function
FriendStatusWithCounter(props)

const
[count, setCount]
=
useState(0);
useEffect(()
=>
 document.title  =
`Ви натиснули
$count>
раз`;
>);
const
[isOnline, setIsOnline]
=
useState(null);
useEffect(()
=>
 ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return
()
=>
 ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
>;
>);
function
handleStatusChange(status)

setIsOnline(status.isOnline);
>
// .

Хуки дають вам можливість організувати побічні ефекти в компоненті пов'язаних частин (наприклад, додавання або скасування підписки), замість того, щоб змушувати вас ділити все відповідно до методів життєвого циклу.

Докладне пояснення

Ви можете дізнатися більше про useEffect на сторінці Використання ефекту хука.

Хуки - це функції JavaScript, які накладають два додаткові правила:

  • Хуки слід викликати лише на верхньому рівні. Не викликайте хуки всередині циклів, умов чи вкладених функцій.
  • Хуки слід викликати лише із функціональних компонентів React. Не викликайте хуки із звичайних JavaScript-функцій. Є тільки один виняток, звідки можна викликати хуки - це ваші хуки. Ми розповімо про них далі.

Ми розробили спеціальний плагін для лінтера, який допомагає забезпечувати дотримання цих правил. Ми розуміємо, що ці правила можуть здатися трохи незрозумілими та накладати певні обмеження, але вони дуже важливі для правильної роботи хуків.

Докладне пояснення

Ви можете дізнатись більше на сторінці Правила хуків.

💡 Створення власних хуків

Іноді потрібно повторно використовувати однакову логіку стану у кількох компонентах. Традиційно використовувалися два підходи: компоненти вищого ладу та рендер-пропси. За допомогою хуків користувача це завдання вирішується без додавання непотрібних компонентів у ваше дерево.

Раніше на цій сторінці ми розглядали компонент FriendStatus, який викликав хуки useState і useEffect, щоб підписатися на статус друга в мережі. Допустимо, ми хочемо ще раз використовувати цю логіку з підпискою, але вже в іншому компоненті.

Перш за все, давайте витягнемо цю логіку в хук користувача useFriendStatus

import React,
 useState, useEffect  >
from
'react';
function
useFriendStatus(friendID)

const
[isOnline, setIsOnline]
=
useState(null);
function
handleStatusChange(status)

setIsOnline(status.isOnline);
>
useEffect(()
=>
 ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return
()
=>
 ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
>;
>);
return isOnline;
>

Хук приймає friendID як аргумент і повертає змінну, яка показує, чи в мережі наш друг чи ні.

Тепер ми можемо використовувати цей хук в обох компонентах:

function
FriendStatus(props)

const isOnline  =
useFriendStatus(props.friend.id);
if
(isOnline  ===
null)

return
'Завантаження. ';
>
return isOnline  ?
'У мережі'
:
'Не в мережі';
>
function
FriendListItem(props)

const isOnline  =
useFriendStatus(props.friend.id);
return
(
li
style=
color: isOnline  ?
'green'
:
'black'
>>>
props.friend.name>
li>
);
>

Стани кожного компонента жодним чином не залежать один від одного. Хуки - це спосіб використовувати повторно логіку стану, а чи не сам стан. Більше того, кожне звернення до хука забезпечує цілком ізольований стан. Ви навіть можете використовувати той самий хук кілька разів в одному компоненті.

Користувальницькі хуки - це більшою мірою угода, ніж доповнення. Якщо ім'я функції починається з ” use ” і вона викликає інші хуки, ми розцінюємо це як хук користувача. Якщо ви будете дотримуватись угоди прокористування когось при назві хуків, це дозволить нашому плагіну для лінтера знайти баги в коді, який використовує хуки.

Є багато підходящих випадків, щоб написати користувальницькі хуки, такі як робота з формами, анімація, декларативні підписки, таймери і, мабуть, багато інших, про які ми навіть не думали. Ми з нетерпінням очікуємо побачити, які ж користувацькі хуки спільнота React зможе придумати.

Є ще кілька менш використовуваних вбудованих хуків, які можуть знадобитися. Наприклад, за допомогою useContext ви можете підписатися на контекст React без використання будь-яких вкладень.

function
Example()

const locale  =
useContext(LocaleContext);
const theme  =
useContext(ThemeContext);
// .
>

А хук useReducer дає можливість керувати внутрішнім станом складнішого компонента за допомогою редюсера.

function
Todos()

const
[todos, dispatch]
=
useReducer(todosReducer);
// .

Докладне пояснення

Ви можете дізнатися більше про всі вбудовані хуки на сторінці API-довідника хуків.

Фух, давайте перестанемо поспішати і трохи охолодимо запал! Якщо вам щось незрозуміло або ви хочете дізнатися про щось докладніше, ви можете почати читати наступні сторінки, починаючи з документації хука стану.

Ви також можете переглянути API-довідник хуків та FAQ хуків.

І нарешті, не проходьте повз вступну сторінку, на якій ви дізнаєтеся чому ми додаємо хуки і як ми плануємо використовувати їх разом із класами без необхідності переписувати наші додатки.

Схожі статті

  • Що таке таблиця об'єкт об'єкт
  • Що таке Кастер у підвісці
  • Що таке соус Шою
  • Що таке МСФЗ простими словами
  • Що таке сорт м'яса
  • Що таке Фасадна панель для посудомийної машини
  • Що таке джунглі історія 5 клас
  • Що таке обсяг простими словами
  • Недавні статті

  • Чому взуття скрипить при ходьбі
  • Коли день народження у стрічці
  • Чи можна кішці їсти сіль
  • Варіанти планування ділянки 15 соток прямокутної форми
  • Що означає півмісяця знак
  • Рейсмусовий верстат для чого
  • У якому віці парують свиней
  • У чому полягає принцип нарахування та у яких випадках він застосовується