Български

Отключете силата на преизползваемата логика във вашите React приложения с персонализирани куки. Научете как да създавате и използвате персонализирани куки за по-чист и лесен за поддръжка код.

Персонализирани куки (Custom Hooks): Модели за преизползваема логика в React

React куките (Hooks) революционизираха начина, по който пишем React компоненти, като въведоха състояние (state) и функции на жизнения цикъл (lifecycle) във функционалните компоненти. Сред многото предимства, които предлагат, персонализираните куки се открояват като мощен механизъм за извличане и повторно използване на логика в множество компоненти. Тази блог публикация ще се потопи дълбоко в света на персонализираните куки, изследвайки техните предимства, създаване и използване с практически примери.

Какво представляват персонализираните куки?

По същество, персонализираната кука е JavaScript функция, която започва с думата "use" и може да извиква други куки. Те ви позволяват да извличате логиката на компонента в преизползваеми функции. Това е мощен начин за споделяне на логика със състояние, странични ефекти или други сложни поведения между компоненти, без да се прибягва до render props, компоненти от по-висок ред (higher-order components) или други сложни модели.

Ключови характеристики на персонализираните куки:

Предимства от използването на персонализирани куки

Персонализираните куки предлагат няколко значителни предимства в разработката с React:

Създаване на първата ви персонализирана кука

Нека илюстрираме създаването на персонализирана кука с практически пример: кука, която проследява размера на прозореца.

Пример: useWindowSize

Тази кука ще връща текущата ширина и височина на прозореца на браузъра. Тя също така ще актуализира тези стойности, когато прозорецът бъде преоразмерен.

import { useState, useEffect } from 'react';

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

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

    window.addEventListener('resize', handleResize);

    // Премахване на event listener при почистване
    return () => window.removeEventListener('resize', handleResize);
  }, []); // Празният масив гарантира, че ефектът се изпълнява само при монтиране

  return windowSize;
}

export default useWindowSize;

Обяснение:

  1. Импортиране на необходимите куки: Импортираме useState и useEffect от React.
  2. Дефиниране на куката: Създаваме функция с име useWindowSize, спазвайки конвенцията за именуване.
  3. Инициализиране на състоянието: Използваме useState, за да инициализираме състоянието windowSize с началната ширина и височина на прозореца.
  4. Настройване на Event Listener: Използваме useEffect, за да добавим event listener за преоразмеряване към прозореца. Когато прозорецът се преоразмери, функцията handleResize актуализира състоянието windowSize.
  5. Почистване: Връщаме функция за почистване от useEffect, за да премахнем event listener-а, когато компонентът се демонтира. Това предотвратява изтичане на памет.
  6. Връщане на стойности: Куката връща обекта windowSize, съдържащ текущата ширина и височина на прозореца.

Използване на персонализираната кука в компонент

Сега, след като създадохме нашата персонализирана кука, нека видим как да я използваме в React компонент.

import React from 'react';
import useWindowSize from './useWindowSize';

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

  return (
    

Ширина на прозореца: {width}px

Височина на прозореца: {height}px

); } export default MyComponent;

Обяснение:

  1. Импортиране на куката: Импортираме персонализираната кука useWindowSize.
  2. Извикване на куката: Извикваме куката useWindowSize в рамките на компонента.
  3. Достъп до стойностите: Деструктурираме върнатия обект, за да получим стойностите width и height.
  4. Изобразяване на стойностите: Изобразяваме стойностите за ширина и височина в потребителския интерфейс на компонента.

Всеки компонент, който използва useWindowSize, ще се актуализира автоматично, когато размерът на прозореца се промени.

По-сложни примери

Нека разгледаме някои по-напреднали случаи на употреба на персонализирани куки.

Пример: useLocalStorage

Тази кука ви позволява лесно да съхранявате и извличате данни от локалното хранилище (local storage).

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  // Състояние за съхраняване на нашата стойност
  // Предаваме начална стойност на useState, така че логиката да се изпълни само веднъж
  const [storedValue, setStoredValue] = useState(() => {
    try {
      // Вземане от локалното хранилище по ключ
      const item = window.localStorage.getItem(key);
      // Парсване на съхранения json или ако няма такъв, връщане на initialValue
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // При грешка също връщаме initialValue
      console.log(error);
      return initialValue;
    }
  });

  // Връщаме обвита версия на setter функцията на useState, която...
  // ... запазва новата стойност в localStorage.
  const setValue = (value) => {
    try {
      // Позволяваме стойността да бъде функция, за да имаме същия API като useState
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      // Запазване в локалното хранилище
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
      // Запазване на състоянието
      setStoredValue(valueToStore);
    } catch (error) {
      // По-напреднала имплементация би обработила случая с грешка
      console.log(error);
    }
  };

  useEffect(() => {
    try {
      const item = window.localStorage.getItem(key);
      setStoredValue(item ? JSON.parse(item) : initialValue);
    } catch (error) {
      console.log(error);
    }
  }, [key, initialValue]);

  return [storedValue, setValue];
}

export default useLocalStorage;

Употреба:

import React from 'react';
import useLocalStorage from './useLocalStorage';

function MyComponent() {
  const [name, setName] = useLocalStorage('name', 'Гост');

  return (
    

Здравейте, {name}!

setName(e.target.value)} />
); } export default MyComponent;

Пример: useFetch

Тази кука капсулира логиката за извличане на данни от API.

import { useState, useEffect } from 'react';

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

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`HTTP грешка! статус: ${response.status}`);
        }
        const json = await response.json();
        setData(json);
        setLoading(false);
      } catch (error) {
        setError(error);
        setLoading(false);
      }
    }

    fetchData();
  }, [url]);

  return { data, loading, error };
}

export default useFetch;

Употреба:

import React from 'react';
import useFetch from './useFetch';

function MyComponent() {
  const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/todos/1');

  if (loading) return 

Зареждане...

; if (error) return

Грешка: {error.message}

; return (

Заглавие: {data.title}

Завършено: {data.completed ? 'Да' : 'Не'}

); } export default MyComponent;

Най-добри практики за персонализирани куки

За да сте сигурни, че вашите персонализирани куки са ефективни и лесни за поддръжка, следвайте тези най-добри практики:

Често срещани капани, които да избягвате

Напреднали модели

Композиране на персонализирани куки

Персонализираните куки могат да се композират заедно, за да се създаде по-сложна логика. Например, можете да комбинирате кука useLocalStorage с кука useFetch, за да запазвате автоматично извлечените данни в локалното хранилище.

Споделяне на логика между куки

Ако няколко персонализирани куки споделят обща логика, можете да извлечете тази логика в отделна помощна функция и да я използвате повторно и в двете куки.

Използване на Context с персонализирани куки

Персонализираните куки могат да се използват в комбинация с React Context за достъп и актуализиране на глобалното състояние. Това ви позволява да създавате преизползваеми компоненти, които са наясно с глобалното състояние на приложението и могат да взаимодействат с него.

Примери от реалния свят

Ето няколко примера за това как персонализираните куки могат да се използват в приложения от реалния свят:

Пример: кука useGeolocation за междукултурни приложения като картографски или куриерски услуги

import { useState, useEffect } from 'react';

function useGeolocation() {
  const [location, setLocation] = useState({
    latitude: null,
    longitude: null,
    error: null,
  });

  useEffect(() => {
    if (!navigator.geolocation) {
      setLocation({
        latitude: null,
        longitude: null,
        error: 'Геолокацията не се поддържа от този браузър.',
      });
      return;
    }

    const watchId = navigator.geolocation.watchPosition(
      (position) => {
        setLocation({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          error: null,
        });
      },
      (error) => {
        setLocation({
          latitude: null,
          longitude: null,
          error: error.message,
        });
      }
    );

    return () => navigator.geolocation.clearWatch(watchId);
  }, []);

  return location;
}

export default useGeolocation;

Заключение

Персонализираните куки са мощен инструмент за писане на по-чист, по-преизползваем и по-лесен за поддръжка React код. Чрез капсулиране на сложна логика в персонализирани куки, можете да опростите вашите компоненти, да намалите дублирането на код и да подобрите цялостната структура на вашите приложения. Прегърнете персонализираните куки и отключете техния потенциал за изграждане на по-стабилни и мащабируеми React приложения.

Започнете, като идентифицирате области във вашата съществуваща кодова база, където логиката се повтаря в множество компоненти. След това, рефакторирайте тази логика в персонализирани куки. С течение на времето ще изградите библиотека от преизползваеми куки, които ще ускорят процеса ви на разработка и ще подобрят качеството на вашия код.

Не забравяйте да следвате най-добрите практики, да избягвате често срещаните капани и да изследвате напреднали модели, за да извлечете максимума от персонализираните куки. С практика и опит ще станете майстор на персонализираните куки и по-ефективен React разработчик.