← Назад к вопросам

Какие хуки React знаешь?

2.0 Middle🔥 302 комментариев
#React#Архитектура и паттерны

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основные хуки React (Hooks)

Я работаю с React с момента выхода хуков в 2019 году (React 16.8) и активно применяю их во всех проектах. Хуки — это функции, которые позволяют использовать состояние и другие возможности React без написания классов. Они революционизировали разработку на React, сделав код более компактным, читаемым и reusable.

Все хуки можно разделить на три основные категории: базовые (используются в 95% компонентов), дополнительные (для оптимизации и side effects) и пользовательские (собственная логика).


📌 Базовые хуки (Basic Hooks)

Эти хуки используются практически в каждом функциональном компоненте.

  1. useState
    Управляет внутренним состоянием компонента. Возвращает массив из двух элементов: текущее значение состояния и функцию для его обновления.

```javascript
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // Инициализация

  return (
    <div>
      <p>Вы кликнули {count} раз</p>
      <button onClick={() => setCount(count + 1)}>
        Увеличить
      </button>
      {/* Функциональное обновление, если новое состояние зависит от предыдущего */}
      <button onClick={() => setCount(prev => prev - 1)}>
        Уменьшить
      </button>
    </div>
  );
}
```

2. useEffect

    Позволяет выполнять **side effects** в функциональных компонентах: запросы к API, подписки на события, ручное изменение DOM. Заменяет `componentDidMount`, `componentDidUpdate` и `componentWillUnmount`.

```javascript
useEffect(() => {
  // Код для выполнения после каждого рендера
  console.log('Эффект выполнился');

  // Функция очистки (аналог componentWillUnmount)
  return () => {
    console.log('Очистка эффекта');
  };
}, [dep1, dep2]); // Массив зависимостей. Эффект запустится только при их изменении.
```
    **Важные варианты:**
    *   `useEffect(() => {...})` — выполняется после **каждого** рендера.
    *   `useEffect(() => {...}, [])` — выполняется один раз, после **первого** монтирования (аналог `componentDidMount`).
    *   `useEffect(() => {...}, [dep])` — выполняется при изменении зависимости `dep`.

  1. useContext
    Позволяет подписаться на контекст React, избегая пропс дриллинга (prop drilling). Принимает объект контекста, созданный `React.createContext`, и возвращает его текущее значение.

```javascript
const ThemeContext = React.createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext); // Получаем значение напрямую
  return <button className={theme}>Кнопка</button>;
}
```

🛠 Дополнительные хуки (Additional Hooks)

Эти хуки решают более специфические задачи: оптимизация, работа с refs, управление сложным состоянием.

  1. useReducer
    Альтернатива `useState` для управления сложной логикой состояния. Принимает редюсер `(state, action) => newState` и начальное состояние. Похож на Redux в миниатюре.

```javascript
const initialState = { count: 0 };

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

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
    </>
  );
}
```

5. useRef

    Создает мутируемый объект, свойство `.current` которого сохраняется между рендерами. Основные use cases:
    *   Доступ к DOM-элементам.
    *   Хранение мутируемых значений, которые не должны вызывать ререндер.

```javascript
function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const renderCount = useRef(0); // Не вызывает ререндер!

  useEffect(() => {
    renderCount.current = renderCount.current + 1;
  });

  const onButtonClick = () => {
    inputEl.current.focus(); // Прямой доступ к DOM-ноде
  };

  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Фокус на поле</button>
      <p>Компонент отрендерен {renderCount.current} раз</p>
    </>
  );
}
```

6. useMemo и useCallback

    Хуки для **оптимизации производительности**, предотвращающие лишние вычисления и ререндеры дочерних компонентов.
    *   `useMemo` — кеширует результат вычислений. Пересчитывает только при изменении зависимостей.
    *   `useCallback` — кеширует саму функцию, а не её значение. Критично для оптимизированных дочерних компонентов, которые зависят от `React.memo`.

```javascript
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]);
```

7. useImperativeHandle

    Позволяет кастомизировать значение, которое передается родительскому компоненту при использовании `ref`. Используется редко, в связке с `React.forwardRef`.

  1. useLayoutEffect
    Имеет ту же сигнатуру, что и `useEffect`, но выполняется синхронно **после всех мутаций DOM**, но до того, как браузер отрисует изменения. Используется для измерений DOM или синхронных мутаций, чтобы избежать "мерцания".

  1. useDebugValue
    Позволяет добавлять кастомные метки для пользовательских хуков в React DevTools. Упрощает отладку.


🧩 Пользовательские хуки (Custom Hooks)

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

// Пользовательский хук для подписки на онлайн-статус друга
function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  }, [friendID]); // Переподписка при смене friendID

  return isOnline;
}

// Использование в компоненте
function FriendListItem({ friend }) {
  const isOnline = useFriendStatus(friend.id); // Логика переиспользуется!
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {friend.name}
    </li>
  );
}

🎯 Правила хуков (Rules of Hooks)

При работе с хуками необходимо строго соблюдать два правила:

  1. Вызывайте хуки только на верхнем уровне. Не вызывайте их внутри циклов, условий или вложенных функций.
  2. Вызывайте хуки только из React-функций или из пользовательских хуков.

Для автоматического контроля этих правил используется линтер ESLint с плагином eslint-plugin-react-hooks.

Итог: Хуки — это фундаментальная и неотъемлемая часть современной экосистемы React. Они обеспечивают более прямой способ использования возможностей React (состояние, жизненный цикл, контекст) через функции, значительно улучшая композицию, читаемость и тестируемость кода. Понимание и грамотное применение всех типов хуков, особенно useState, useEffect, useMemo/useCallback и умение создавать custom hooks, является ключевым навыком для профессионального Frontend-разработчика на React.

Какие хуки React знаешь? | PrepBro