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

Что возвращает кастомный хук?

1.0 Junior🔥 233 комментариев
#React

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

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

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

Что возвращает кастомный хук React?

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

Основные паттерны возвращаемых значений

  1. Одиночное значение (примитив, объект, массив) Хук может возвращать одно значение, например, текущее состояние, результат вычислений или флаг.

    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; // Возвращает число
    }
    
  2. Массив значений (по аналогии с useState) Возврат массива позволяет легко деструктурировать возвращаемые значения с любыми именами.

    function useToggle(initialValue = false) {
      const [value, setValue] = useState(initialValue);
      const toggle = () => setValue(prev => !prev);
      return [value, toggle]; // Возвращает массив: [состояние, функция]
    }
    // Использование: const [isOn, toggleIsOn] = useToggle();
    
  3. Объект с именованными свойствами Самый популярный подход, так как он улучшает читаемость и устойчивость к рефакторингу.

    function useFetch(url) {
      const [data, setData] = useState(null);
      const [loading, setLoading] = useState(true);
      const [error, setError] = useState(null);
    
      useEffect(() => {
        fetch(url)
          .then(res => res.json())
          .then(data => setData(data))
          .catch(err => setError(err))
          .finally(() => setLoading(false));
      }, [url]);
    
      return { data, loading, error }; // Возвращает объект
    }
    // Использование: const { data, loading, error } = useFetch('/api');
    

Ключевые принципы возвращаемых значений

  • Согласованность типа возврата: Внутри одного хука следует придерживаться одного типа возврата (например, всегда объект или всегда массив).
  • Иммутабельность возвращаемых функций: Если хук возвращает функции (например, обработчики событий), они должны быть стабильными между рендерами, чтобы избежать лишних ре-эффектов. Для этого используйте useCallback.
  • Опциональность возвращаемых полей: В объекте могут быть опциональные поля, которые заполняются при определённых условиях (например, error только при ошибке).

Пример комплексного хука с несколькими возвращаемыми значениями

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });

  const setValue = useCallback((value) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.error(error);
    }
  }, [key, storedValue]);

  const removeValue = useCallback(() => {
    try {
      window.localStorage.removeItem(key);
      setStoredValue(initialValue);
    } catch (error) {
      console.error(error);
    }
  }, [key, initialValue]);

  return { 
    value: storedValue, 
    setValue, 
    removeValue,
    isPersisted: !!window.localStorage.getItem(key)
  };
}

Важные нюансы

  • Хук всегда должен возвращать значение — даже если это undefined или null. Не должно быть условного возврата в середине выполнения хука.
  • Возвращаемые значения должны быть связаны с логикой хука — хук должен решать одну конкретную задачу и возвращать только необходимые для этой задачи данные.
  • Мемоизация сложных объектов — если возвращается новый объект при каждом рендере, это может вызывать лишние ре-рендеры. В таких случаях полезно использовать useMemo.

Итог: Кастомный хук возвращает то, что задумал разработчик — данные, функции или их комбинацию в виде примитива, массива или объекта. Выбор формата возврата зависит от контекста использования и должен соответствовать принципам предсказуемости, согласованности и удобства использования в компонентах. Правильно спроектированный возвращаемый API хука значительно упрощает его повторное использование и поддержку.