Skip to content

Instantly share code, notes, and snippets.

@dmitry-osin
Created August 2, 2025 16:37
Show Gist options
  • Save dmitry-osin/a740f454745671587a4bec70eafe0026 to your computer and use it in GitHub Desktop.
Save dmitry-osin/a740f454745671587a4bec70eafe0026 to your computer and use it in GitHub Desktop.
Шпаргалка по хукам React

Подробное объяснение React-хуков с примерами

Что такое хуки?

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

1. useState

Что делает: Позволяет объявлять внутреннее состояние в функциональных компонентах.

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

  • При первом рендере значение из аргумента (например, 0) становится начальным для состояния.
  • Возвращает массив: [значение, функция для обновления].
  • Можно создавать столько useState, сколько нужно разных переменных состояния.

Особенности:

  • Обновление состояния асинхронное.
  • При каждом обновлении состояния компонент перерисовывается.

Пример:

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // начальное значение = 0

  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  );
}

2. useEffect

Что делает: Управляет побочными эффектами — запросы к API, подписки, работа с DOM.

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

  • useEffect(callback, [dependencies])
  • callback срабатывает после DOM-отрисовки (рендера).
  • Если передать зависимость (массив второго аргумента), хук будет срабатывать только при изменении этих переменных.
  • Если массив пуст, эффект выполнится только 1 раз после маунта (аналог componentDidMount).

Особенности:

  • Можно возвращать функцию очистки (cleanup) — полезно для удаления таймеров, подписок перед размонтированием компонента.

Пример:

import { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => setSeconds(s => s + 1), 1000);
    return () => clearInterval(interval); // очистка интервала при размонтировании
  }, []);

  return <div>Прошло секунд: {seconds}</div>;
}

3. useContext

Что делает: Дает доступ к глобальному контексту без пропсов.

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

  • Контекст создаётся через createContext(defaultValue).
  • В любом компоненте можно получить актуальное значение через useContext(Context).
  • Используется для передачи тем, локализации, данных пользователя и др.

Особенности:

  • Изменение значения в Provider пересчитает все подписанные на контекст компоненты.

Пример:

import { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function ThemeButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Тема: {theme}</button>;
}

4. useRef

Что делает: Сохраняет изменяемое значение между рендерами без триггера перерисовки.

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

  • Возвращает объект вида { current: значение }.
  • Обычно используется для сохранения ссылок на DOM-элементы, хранения таймеров, внешних значений.

Особенности:

  • Изменение .current не вызывает повторный рендер.
  • Отлично подходит для инкапсуляции "промежуточных" данных.

Пример:

import { useRef } from 'react';

function InputFocus() {
  const inputRef = useRef();

  return (
    <>
      <input ref={inputRef} />
      <button onClick={() => inputRef.current.focus()}>Фокус!</button>
    </>
  );
}

5. useMemo

Что делает: Мемоизирует (кеширует) результат функции, чтобы не выполнять дорогие вычисления при каждом рендере.

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

  • Выполняет функцию только если изменяются зависимости из массива.
  • Возвращает закешированный результат.

Особенности:

  • Использовать для реально тяжелых вычислений, иначе усложняет код без ощутимой пользы.
  • Не мемоизирует функции — для этого есть useCallback.

Пример:

import { useMemo, useState } from 'react';

function ExpensiveComponent({ num }) {
  const [count, setCount] = useState(0);

  const fib = useMemo(() => {
    function fibonacci(n) {
      if (n <= 1) return n;
      return fibonacci(n - 1) + fibonacci(n - 2);
    }
    return fibonacci(num);
  }, [num]);

  return (
    <div>
      Fibonacci: {fib}
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

6. useCallback

Что делает: Мемоизирует функцию, чтобы не создавать новую при каждом рендере.

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

  • Возвращает ту же функцию между рендерами, пока не изменены зависимости.
  • Полезно при передаче колбеков вниз по дереву и оптимизациях.

Особенности:

  • Если колбек зависит от пропсов или стейта, их обязательно указать в массиве зависимостей.

Пример:

import { useState, useCallback } from 'react';

function MyComponent() {
  const [value, setValue] = useState(0);

  const increment = useCallback(() => {
    setValue(v => v + 1);
  }, []);

  return <button onClick={increment}>{value}</button>;
}

7. useReducer

Что делает: Позволяет управлять сложным состоянием с помощью редьюсера (аналог Redux, но локально).

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

  • Принимает функцию reducer(state, action) и начальное состояние.
  • Возвращает массив: [state, dispatch].
  • dispatch отправляют action, и reducer на его основе возвращает новое состояние.

Особенности:

  • Отлично работает для сложного состояния, состоящего из нескольких полей или требующего сложной логики изменений.

Пример:

import { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    default:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <button onClick={() => dispatch({ type: 'increment' })}>
      Счет: {state.count}
    </button>
  );
}

8. Когда и как использовать хуки?

  • useState: для управления простыми данными, зависящими от пользователя.
  • useEffect: для работы с асинхронностью, подписками, чтением локального хранилища и побочными задачами.
  • useContext: когда нужно глобально прокидывать данные глубоко в дерево компонентов.
  • useRef: когда нужен доступ к DOM-элементу или "устойчивое" значение между рендерами (например, для хранения id таймера).
  • useMemo/useCallback: только при явных проблемах с производительностью, связанных с пересозданием функций и повторным рендером тяжелых вычислений или потомков.
  • useReducer: если компонент управляет сложной логикой состояния или несколькими связанными данными.

9. Правила использования хуков

  • Хуки вызываются всегда на верхнем уровне функционального компонента.
  • Хуки нельзя использовать внутри условий, циклов, вложенных функций (иначе React не может обеспечить корректность работы внутреннего стека хуков).
  • Хуки используются только в функциях-компонентах или кастомных хуках, не в обычных JS-функциях и не в классах.

10. Кастомные хуки

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

Пример:

import { useState, useEffect } from 'react';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}

Использование:

function Example() {
  const width = useWindowWidth();
  return <div>Ширина окна: {width}</div>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment