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

На список статей
Blog image

Track My Time — Управляй временем эффективно и достигай большего!
"Ваш незаменимый помощник в управлении проектами и учете времени! Отслеживайте задачи, распределяйте ресурсы и контролируйте каждую минуту работы. Повышайте эффективность, упрощайте процессы и достигайте результатов быстрее. Начните работать с нами и добейтесь успеха вместе!"

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

Пользовательский хук — это просто JavaScript-функция, которая использует встроенные хуки и упрощает повторное использование логики. Давайте разберем, как их создавать.

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

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

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

Эти хуки часто используются для управления состоянием на уровне компонента. Но что делать, если вам нужно использовать один и тот же набор данных в нескольких местах? Решением может стать создание собственного хука.

Как создавать пользовательские хуки

Пользовательский хук — это функция, которая следует правилам хуков (например, она должна начинаться с "use") и может использовать другие хуки внутри себя.

Давайте создадим простой пользовательский хук, который управляет состоянием счетчика.

Пример 1: Создание простого пользовательского хука useCounter
import { useState } from "react";

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

 const increment = () => setCount(count + 1);
 const decrement = () => setCount(count - 1);
 const reset = () => setCount(0);

 return { count, increment, decrement, reset };
}

export default useCounter;


Что здесь происходит?

  1. Мы создали функцию useCounter, которая использует хук useState для управления состоянием счетчика.
  2. Хук возвращает объект с текущим значением счетчика (count) и функциями для увеличения, уменьшения и сброса значения.
  3. Теперь этот хук можно использовать в любом компоненте.
Использование хука useCounter:
import React from "react";
import useCounter from "./useCounter";

function CounterComponent() {
 const { count, increment, decrement, reset } = useCounter(10);

 return (
   <div>
     <p>Счёт: {count}</p>
     <button onClick={increment}>Увеличить</button>
     <button onClick={decrement}>Уменьшить</button>
     <button onClick={reset}>Сбросить</button>
   </div>
 );
}

export default CounterComponent;

Здесь мы импортируем наш пользовательский хук useCounter и используем его для управления состоянием счетчика в компоненте. Все просто и понятно!

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

Теперь, когда мы разобрались, как создавать хуки, возникает вопрос: когда их использовать? Основная причина — это повторное использование логики. Если вы обнаруживаете, что один и тот же код используется в нескольких компонентах, вместо копирования логики, вы можете вынести ее в отдельный пользовательский хук.

Пример 2: Хук для запроса данных — useFetch

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

import { useState, useEffect } from "react";

function useFetch(url) {
 const [data, setData] = useState(null);
 const [loading, setLoading] = useState(true);
 const [error, setError] = useState(null);

 useEffect(() => {
   const fetchData = async () => {
     setLoading(true);
     try {
       const response = await fetch(url);
       const result = await response.json();
       setData(result);
     } catch (error) {
       setError(error);
     }
     setLoading(false);
   };

   fetchData();
 }, [url]);

 return { data, loading, error };
}

export default useFetch;

Что здесь происходит?

  1. Хук useFetch принимает URL-адрес для запроса данных.
  2. Используем useState для хранения состояния данных, загрузки и ошибки.
  3. useEffect выполняет запрос, когда компонент монтируется или изменяется URL.
  4. Возвращаем объект с данными, статусом загрузки и ошибкой.
Использование хука useFetch:
import React from "react";
import useFetch from "./useFetch";

function DataComponent() {
 const { data, loading, error } = useFetch("https://api.example.com/data");

 if (loading) return <p>Загрузка...</p>;
 if (error) return <p>Ошибка: {error.message}</p>;

 return (
   <div>
     <h1>Данные:</h1>
     <pre>{JSON.stringify(data, null, 2)}</pre>
   </div>
 );
}

export default DataComponent;

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

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

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

Пример 3: Хук для отслеживания размеров окна — useWindowSize

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

import { useState, useEffect } from "react";

function useWindowSize() {
 const [windowSize, setWindowSize] = useState({
   width: window.innerWidth,
   height: window.innerHeight,
 });

 useEffect(() => {
   const handleResize = () => {
     setWindowSize({
       width: window.innerWidth,
       height: window.innerHeight,
     });
   };

   window.addEventListener("resize", handleResize);

   return () => {
     window.removeEventListener("resize", handleResize);
   };
 }, []);

 return windowSize;
}

export default useWindowSize;

Что здесь происходит?

  1. Мы используем хук useState для хранения текущих размеров окна.
  2. Хук useEffect добавляет обработчик события resize, который обновляет состояние, когда окно изменяется.
  3. Возвращаем текущее состояние размеров окна.
Использование хука useWindowSize:
import React from "react";
import useWindowSize from "./useWindowSize";

function WindowSizeComponent() {
 const { width, height } = useWindowSize();

 return (
   <div>
     <p>Ширина окна: {width}px</p>
     <p>Высота окна: {height}px</p>
   </div>
 );
}

export default WindowSizeComponent;

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

Комментарии

Пока нет комментариев

Добавить комментарий