Можно ли вынести функционал в пользовательский хук?

Да, в React можно вынести функционал в пользовательский хук. Введение пользовательских хуков в React версии 16.8 было одним из значительных улучшений, добавленных в фреймворк.

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

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

Чтобы создать пользовательский хук, вы должны использовать префикс "use" при названии функции. Пользовательский хук должен использовать другие хуки или композицию других пользовательских хуков.

Например, допустим, у вас есть компонент, который отслеживает состояние загрузки данных и отрисовывает результат:

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

const useDataLoader = (url) => {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    setIsLoading(true);

    fetch(url)
      .then(response => response.json())
      .then(data => {
        setData(data);
        setIsLoading(false);
      })
      .catch(error => console.error(error));
  }, [url]);

  return { data, isLoading };
};

const ExampleComponent = () => {
  const { data, isLoading } = useDataLoader('https://api.example.com/data');

  if (isLoading) {
    return <div>Loading...</div>;
  }

  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
};

Здесь мы создали пользовательский хук useDataLoader, который принимает URL в качестве аргумента и возвращает данные и состояние загрузки. В компоненте ExampleComponent мы используем этот хук, чтобы получить данные и отобразить их.

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