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

Какие знаешь Hook для оптимизации?

2.0 Middle🔥 241 комментариев
#React

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

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

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

React Hooks для оптимизации производительности

В React, помимо базовых хуков (useState, useEffect, useContext), существуют специальные хуки, предназначенные для оптимизации производительности приложений. Они помогают избежать ненужных ререндеров, мемоизировать вычисления и управлять сложными состояниями эффективно. Вот ключевые хуки для оптимизации:

useMemo

useMemo используется для мемоизации (запоминания) результатов вычислений. Он возвращает мемоизированное значение, которое пересчитывается только при изменении указанных зависимостей (dependencies).

import React, { useMemo } from 'react';

function ExpensiveComponent({ list }) {
  const sortedList = useMemo(() => {
    return list.sort((a, b) => a.value - b.value);
  }, [list]); // Пересчитывается только при изменении `list`

  return <div>{sortedList.map(item => <p key={item.id}>{item.value}</p>)}</div>;
}

Применение:

  • Когда вычисление требует значительных ресурсов (фильтрация, сортировка больших данных).
  • Для предотвращения повторных вычислений при каждом ререндере.

useCallback

useCallback мемоизирует функции, предотвращая их создание при каждом ререндере. Это особенно важно для функций, передаваемых вниз по дереву компонентов (например, в useEffect или как пропсы к чистым компонентам).

import React, { useState, useCallback } from 'react';

function ParentComponent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]); // Функция создается только при изменении `count`

  return <ChildComponent onClick={handleClick} />;
}

Применение:

  • Когда функция передается как пропс к оптимизированным компонентам (например, обернутым в React.memo).
  • Для предотвращения ненужных ререндеров дочерних компонентов.

useReducer

useReducer предлагает альтернативный подход к управлению состоянием, особенно для сложных или многосвязанных данных. Он может быть более эффективным, чем useState, когда логика изменений состояния включает множество действий или требует централизованного управления.

import React, { useReducer } from 'react';

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: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </>
  );
}

Применение:

  • Для комплексного состояния с множеством действий.
  • Когда логика состояния должна быть отделена от компонента.

useRef

useRef создает mutable (изменяемый) объект, который сохраняет свое значение между ререндерами без их провоцирования. Это полезно для прямого доступа к DOM элементам или сохранения значений, не влияющих на визуальный вывод.

import React, { useRef, useEffect } from 'react';

function FocusInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus(); // Доступ к DOM элементу без ререндера
  }, []);

  return <input ref={inputRef} type="text" />;
}

Применение:

  • Для управления фокусом, позицией скролла или другими DOM операциями.
  • Чтобы хранить предыдущие значения состояния или другие данные без ререндеров.

useTransition и useDeferredValue

Это хуки, представленные в React 18 для управления приоритизацией ререндеров и улучшения пользовательского восприятия производительности.

useTransition позволяет маркировать некоторые обновления состояния как "не критичные" (non-urgent), давая React возможность отложить их выполнение, чтобы сначала выполнить более важные обновления.

import React, { useState, useTransition } from 'react';

function SearchComponent() {
  const [query, setQuery] = useState('');
  const [isPending, startTransition] = useTransition();

  const handleChange = (e) => {
    const newQuery = e.target.value;
    setQuery(newQuery); // Критичное обновление
    startTransition(() => {
      // Не критичное обновление, например, фильтрация данных
      filterResults(newQuery);
    });
  };

  return (
    <>
      <input value={query} onChange={handleChange} />
      {isPending ? <span>Loading...</span> : <Results />}
    </>
  );
}

useDeferredValue позволяет отложить обновление части UI, передавая деферрированное значение, которое "отстает" от оригинального.

import React, { useState, useDeferredValue } from 'react';

function DeferredComponent() {
  const [value, setValue] = useState('');
  const deferredValue = useDeferredValue(value); // Отложенное значение

  return (
    <>
      <input value={value} onChange={e => setValue(e.target.value)} />
      <SlowList text={deferredValue} /> // Компонент использует отложенное значение
    </>
  );
}

Заключение

Для максимальной оптимизации, эти хуки часто комбинируются с другими техниками, такими как:

  • React.memo для мемоизации компонентов.
  • Разделение состояния на логические части.
  • Правильное указание зависимостей в хуках.

Ключевые принципы:

  • Используйте useMemo и useCallback только когда есть доказанные проблемы производительности, так как они добавляют overhead.
  • useReducer помогает структурировать сложную логику состояния.
  • useRef незаменим для работы с DOM и сохранения mutable данных.
  • Новые хуки React 18 (useTransition, useDeferredValue) предназначены для улучшения UX в условиях конкурентного рендеринга.

Эти инструменты позволяют создать высокопроизводительные React приложения, минимизируя лишние ререндеры и оптимизируя ресурсы.