12 хуков React, которые должен знать каждый разработчик

Хуки React  —  это многократно используемые части кода. Хуки позволяют инкапсулировать побочные эффекты, компоновать и повторно использовать логику.

Для большинства сценариев использования существуют хуки React. Зачем изобретать колесо, если есть такое огромное количество хуков с открытым исходным кодом, доступные уже сегодня?

1. react-swipeable

react-swipeable  —  это хук обработчика событий React Swipe. В некоторых случаях react-swipeable необходим для создания React-приложений, ориентированных в первую очередь на мобильные устройства.

Демонстрация

Предположим, что вы разрабатываете онлайн-магазин и хотите включить “нативное” мобильное поведение в веб-приложение.

Мобильные пользователи взаимодействуют с приложениями совсем иначе, чем веб-пользователи. В телефонах предусмотрены сенсорные жесты, свайпы, увеличение и уменьшение масштаба и т.д. Почему бы не включить все эти функции в мобильное веб-приложение?

Как это работает

const handlers = useSwipeable({
  onSwiped: (eventData) => console.log("User Swiped", eventData),
  ...config,
});

return <div {...handlers}> swipe here </div>;

Вот все пропсы, к которым вы можете получить доступ при обработке событий:

{
  onSwiped,       // После любого свайпа(SwipeEventData) => void
  onSwipedLeft,   // После свайпа ВЛЕВО (SwipeEventData) => void
  onSwipedRight,  // После свайпа ВПРАВО(SwipeEventData) => void
  onSwipedUp,     // После свайпа ВВЕРХ   (SwipeEventData) => void
  onSwipedDown,   // После свайпа ВНИЗ (SwipeEventData) => void
  onSwipeStart,   // Начало свайпа (SwipeEventData) => void *see details*
  onSwiping,      // Во время свайпа  (SwipeEventData) => void
  onTap,          // После касания     ({ event }) => void

// Передача обратных вызовов, событие предоставлено: ({ event }) => void
  onTouchStartOrOnMouseDown, // Вызывается для `touchstart` и `mousedown`
  onTouchEndOrOnMouseUp,     // Вызывается для `touchend` и `mouseup`
}

Информацию об интеграции и использовании можно найти на странице react-swipeable на сайте NPM.

2. use-resize-observer

use-resize-observer  —  это React-хук, который позволяет измерять ширину и высоту элемента .

Демонстрация на CodeSandbox

Этот хук невероятно удобен при работе с обрезкой, редактированием, обработкой изображений и т.д.

Как использовать

import React from "react";
import ReactDOM from "react-dom";
import useResizeObserver from "use-resize-observer";
import "./styles.css";

const App = () => {
const { ref, width, height } = useResizeObserver<HTMLDivElement>();
return (
<div>
<div className="instructions">Try resizing this div!</div>
<div ref={ref} className="box">
{width}x{height}
</div>
</div>
)};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Дополнительные инструкции можно найти здесь.

3. formik

Formik берет на себя повторяющуюся и утомительную часть работы с формами.

Он отслеживает значения, ошибки, посещенные поля, оркестрирует валидацию и обрабатывает отправку  —  все, с чем вам больше не придется иметь дело. Тратьте меньше времени на подключение обработчиков состояния и изменений.

Как это работает

Допустим, вам нужно добавить форму регистрации в рассылку новостей для блога. Для начала в форме будет только одно поле с именем email. С Formik для этого требуется лишь несколько строк кода.

import React from 'react';
import { useFormik } from 'formik';
const SignupForm = () => {
// Передача хуку useFormik() начальных значений формы и функции submit, которая будет
// вызвана после отправки формы
const formik = useFormik({
initialValues: {
email: '',
},
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
});
return (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="email">Email Address</label>
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
/>
<button type="submit">Submit</button>
</form>
);
};

Источник примера. Информацию об интеграции и использовании можно найти в документации Formik.

4. use-debounce

Дебаунсинг (debouncing) в JavaScript  —  это шаблон, используемый для повышения производительности браузера.

На веб-странице может быть некоторая функциональность, требующая трудоемких вычислений. Например, загрузка изображений, несколько вызовов API и т.д.

Если такие методы будут вызываться слишком часто, это сильно повлияет на производительность браузера.

Дебаунсинг  —  это практика программирования, которая гарантирует, что трудоемкие задачи не будут вызываться так часто.

Как это работает

import React, { useState } from 'react';
import { useDebounce } from 'use-debounce';
export default function Input() {
const [text, setText] = useState('Hello');
const [value] = useDebounce(text, 1000);
return (
<div>
<input
defaultValue={'Hello'}
onChange={(e) => {
setText(e.target.value);
}}
/>
<p>Actual value: {text}</p>
<p>Debounce value: {value}</p>
</div>
);
}

Дополнительную информацию можно найти на странице use-debounce.

5. use-isomorphic-layout-effect

В React есть множество встроенных хуков. Одним из них является useLayoutEffect.

Вот что говорится в документации React о useLayoutEffect:

Сигнатура useLayoutEffect идентична сигнатуре useEffect, но первый хук срабатывает синхронно после всех изменений DOM.

Другими словами, вы можете использовать useLayoutEffect только для браузера. Это проблема, если вы рендерите код React на стороне сервера. Например, при использовании NextJS вы получите следующее сообщение об ошибке:

Предупреждение: useLayoutEffect не действует на сервере, потому что его эффект не может быть закодирован в формат вывода рендерера сервера.

Чтобы избежать этого сообщения об ошибке, используйте useLayoutEffect только в компонентах, рендеринг которых осуществляется исключительно на стороне клиента.

Устранить проблему поможет useIsomorphicLayoutEffect, который переключается между useEffect и useLayoutEffect в зависимости от среды выполнения.

Как использовать

+ import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';

- import { useLayoutEffect } from 'react';

const YourComponent = () => {

+  useIsomorphicLayoutEffect(() => {
   // ваша реализация
}, []);

-  useLayoutEffect(() => {
    // your implementation
  }, []);

};

Больше информации представлено на странице пакета NPM.

6. swr

swr  —  это библиотека React Hooks для получения данных. Ее название происходит от stale-while-revalidate (ресурс считается устаревшим после запроса).

stale-while-revalidate  —  это стратегия аннулирования кэша, доступно изложенная в HTTP RFC 5861.

Как использовать

import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR('/api/user', fetcher)

if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>

return <div>hello {data.name}!</div>

}

swr сначала возвращает данные из кэша (устаревшие), отправляет запрос (повторная проверка) и предоставляет обновленные данные.

Этот хук значительно упрощает логику получения данных. Он также пригодится для оптимизации скорости, корректности и стабильности работы и поможет создавать отличные приложения.

Посредством swr все компоненты будут получать поток обновлений данных постоянно и автоматически. Пользовательский интерфейс станет быстрым и реактивным.

Ознакомиться с полной документацией и примерами можно на сайте swr.vercel.app.

7. react-hotkeys-hook

react-hotkeys-hook предназначен для использования горячих клавиш в компонентах. Хук позволяет прослушивать горячие клавиши декларативным образом и выполнять функцию обратного вызова, как только пользователь нажмет на заданную горячую клавишу.

Как это работает

import { useHotkeys } from 'react-hotkeys-hook';

function ExampleComponent() {
  useHotkeys('a', () => alert('Key a was pressed'))

return (
    <span>Press the a key to see it work.</span>
  )

react-hotkeys-hook также прослушивает нажатия комбинаций клавиш, которые позволяют пользователю выполнить обратный вызов. Представим, что в нашем приложении есть горячие клавиши для обеспечения функциональности. Например, для создания тикета в Jira нужно нажать shift+c.

import { useHotkeys } from 'react-hotkeys-hook';
function CreateIssue() {
const [showIssueCreatorModal, setShowIssueCreatorModal] = useState(false)
useHotkeys('shift+c', () => setShowIssueCreatorModal(true))
return (
<>
{showIssueCreatorModal && <div>MODAL CONTENT</div>}
{!showIssueCreatorModal && <div>issue list</div>}
</>
)
}

Дополнительные примеры можно найти в официальной документации.

8. @use-gesture/react

@use-gesture  —  это библиотека, позволяющая привязывать многофункциональные события, связанные с кликами мышью и касаниями, к любому компоненту и представлению. Настроить жесты с помощью имеющихся пропсов очень просто.

В некоторых приложениях жесты требуются по умолчанию и являются ожидаемыми. Например, жесты  —  обязательное условие для создания приложения по типу Канбан-доски.

import { useSpring, animated } from '@react-spring/web'
import { useDrag } from '@use-gesture/react'
function Example() {
const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 }))
// Установка хука для перетаскивания и определение перемещения компонента на основе данных жеста.
const bind = useDrag(({ down, movement: [mx, my] }) => {
api.start({ x: down ? mx : 0, y: down ? my : 0 })
})
// Привязка к компоненту
return <animated.div {...bind()} style={{ x, y, touchAction: 'none' }} />
}

Доступные хуки

@use-gesture/react экспортирует несколько хуков, которые могут обрабатывать разные жесты. Обязательно ознакомьтесь с ними для более глубокого погружения в тему.

Документация

Его можно использовать отдельно, но чтобы получить максимальную отдачу, стоит объединить его с библиотекой анимации, такой как react-spring. Однако можно использовать и любую другую.

9. react-script-hook

react-script-hook  —  это хук для динамической загрузки внешнего скрипта и определения момента его загрузки. Отлично подходит при работе со сторонними API, такими как Stripe, Twilio и т.д.

Допустим, мы используем API Stripe для приема платежей и не хотим нарушать работу приложения, позволив пользователям взаимодействовать с платежами, когда API еще не полностью загружен. Этот хук решает вышеупомянутую проблему.

import React from 'react';
import { StripeProvider } from 'react-stripe-elements';
import useScript from 'react-script-hook';
import MyCheckout from './my-checkout';
function App() {
const [loading, error] = useScript({ src: 'https://js.stripe.com/v3/' });
if (loading) return <h3>Loading Stripe API...</h3>;
if (error) return <h3>Failed to load Stripe API: {error.message}</h3>;
return (
<StripeProvider apiKey="pk_test_6pRNASCoBOKtIshFeQd4XMUh">
<MyCheckout />
</StripeProvider>
);
}
export default App;

Хук автоматически обрабатывает случаи, когда скрипт уже был загружен (или начал загружаться) из другого экземпляра хука.

Можно смело добавлять одинаковые хуки useScript в несколько компонентов, зависящих от одного и того же внешнего скрипта, и они будут блокировать загрузку только одной копии.

Дополнительные инструкции  —  в документации по пакету NPM.

10. react-scroll-parallax

react-scroll-parallax  —  это хук, который позволяет легко создавать эффекты параллакс-скроллинга для баннеров, изображений и любых других элементов DOM.

Источник

Параллакс-скроллинг предлагает идеальные условия для увлекательной и интерактивной передачи историй. 

Как использовать

Когда элемент прокручивается за пределы области просмотра, применяется эффект CSS translate, основанный на положении исходного элемента относительно области просмотра.

import { useParallax } from 'react-scroll-parallax';

function Component() {
  const parallax = useParallax({
    speed: -10,
  });
  return <div ref={parallax.ref} />;
}

При использовании скорости автоматически применяется CSS-стиль translateY (или translated, если ось прокрутки горизонтальная).

Вы можете вращать элемент вокруг его оси с помощью пропса rotate. Используйте его для вращения элемента вокруг оси z.

const Component = () => {
const parallax = useParallax<HTMLDivElement>({
rotate: [0, 360],
});
return (
<div ref={parallax.ref} className="spinner">
😵‍💫
<div className="diamond">💎</div>
<div className="clown">🤡</div>
<div className="money">💰</div>
<div className="hand">👌🏻</div>
</div>
);
};
Источник

Для более глубокого понимания ознакомьтесь с этим разделом.

11. react-storage-hooks

Хуки react-storage-hooks используются для синхронизации состояния приложения с localStorage и sessionStorage.

Хуки useStorageState и useStorageReducer, включенные в эту библиотеку, работают аналогично useState и useReducer. Однако есть несколько отличий. Здесь дано более подробное описание.

Как использовать

import React from 'react';
import { useStorageState } from 'react-storage-hooks';
function StateCounter() {
const [count, setCount, writeError] = useStorageState(
localStorage,
'state-counter',
0
);
return (
<>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
{writeError && (
<pre>Cannot write to localStorage: {writeError.message}</pre>
)}
</>
);
}

12. @chakra-ui/color-mode

@chakra-ui/color-mode  —  это компонент и хук React, который обеспечивает поддержку светлого и темного режимов с помощью localStorage и matchMedia. Этот хук упрощает пользователям выбор между темной и светлой темой.

Как использовать

Оберните приложение в ColorModeProvider под ThemeProvider.

import * as React from "react"
import { ColorModeProvider } from "@chakra-ui/color-mode"
import theme from "./theme"

function App({ children }) {
  return (
    <ThemeProvider theme={theme}>
      <ColorModeProvider>{children}</ColorModeProvider>
    </ThemeProvider>
  )
}

Затем используйте хук useColorMode в приложении.

function Example() {
const { colorMode, toggleColorMode } = useColorMode()
return (
<header>
<Button onClick={toggleColorMode}>
Toggle {colorMode === "light" ? "Dark" : "Light"}
</Button>
</header>
)
}

Дополнительные инструкции находятся на этой странице.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Trevor-Indrek Lasn: 12 React Hooks Every React Developer Should Know

Предыдущая статья4 уровня владения Makefile
Следующая статьяКак написать на Java функцию, подобную sizeof в C