Slovenčina

Odomknite silu znovupoužiteľnej logiky vo vašich React aplikáciách pomocou vlastných hookov. Naučte sa, ako tvoriť a využívať vlastné hooky pre čistejší a udržateľnejší kód.

Vlastné Hooky: Vzory pre znovupoužiteľnú logiku v Reacte

React Hooky spôsobili revolúciu v spôsobe, akým píšeme React komponenty, zavedením stavu a lifecycle funkcií do funkcionálnych komponentov. Medzi mnohými výhodami, ktoré ponúkajú, vynikajú vlastné hooky ako mocný mechanizmus na extrahovanie a opätovné použitie logiky naprieč viacerými komponentmi. Tento blogový príspevok sa ponorí hlboko do sveta vlastných hookov, preskúma ich výhody, tvorbu a použitie s praktickými príkladmi.

Čo sú vlastné hooky?

V podstate je vlastný hook JavaScriptová funkcia, ktorej názov začína slovom "use" a môže volať iné hooky. Umožňujú vám extrahovať logiku komponentu do znovupoužiteľných funkcií. Je to mocný spôsob, ako zdieľať stavovú logiku, vedľajšie efekty alebo iné komplexné správanie medzi komponentmi bez nutnosti uchyľovať sa k render props, komponentom vyššieho rádu (higher-order components) alebo iným zložitým vzorom.

Kľúčové vlastnosti vlastných hookov:

Výhody používania vlastných hookov

Vlastné hooky ponúkajú niekoľko významných výhod vo vývoji s Reactom:

Vytvorenie vášho prvého vlastného hooku

Poďme si ilustrovať tvorbu vlastného hooku na praktickom príklade: hook, ktorý sleduje veľkosť okna.

Príklad: useWindowSize

Tento hook vráti aktuálnu šírku a výšku okna prehliadača. Taktiež bude tieto hodnoty aktualizovať pri zmene veľkosti okna.

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);

    // Odstránenie event listenera pri čistení
    return () => window.removeEventListener('resize', handleResize);
  }, []); // Prázdne pole zaručuje, že efekt sa spustí iba pri prvom pripojení (mount)

  return windowSize;
}

export default useWindowSize;

Vysvetlenie:

  1. Import potrebných hookov: Importujeme useState a useEffect z Reactu.
  2. Definícia hooku: Vytvoríme funkciu s názvom useWindowSize, dodržiavajúc konvenciu pomenovania.
  3. Inicializácia stavu: Použijeme useState na inicializáciu stavu windowSize s počiatočnou šírkou a výškou okna.
  4. Nastavenie event listenera: Použijeme useEffect na pridanie event listenera pre zmenu veľkosti (resize) na okno. Keď sa veľkosť okna zmení, funkcia handleResize aktualizuje stav windowSize.
  5. Čistenie (Cleanup): Z useEffect vraciame čistiacu funkciu na odstránenie event listenera, keď sa komponent odpojí (unmount). Tým sa predchádza únikom pamäte.
  6. Vrátenie hodnôt: Hook vracia objekt windowSize, ktorý obsahuje aktuálnu šírku a výšku okna.

Použitie vlastného hooku v komponente

Teraz, keď sme vytvorili náš vlastný hook, pozrime sa, ako ho použiť v React komponente.

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

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

  return (
    

Šírka okna: {width}px

Výška okna: {height}px

); } export default MyComponent;

Vysvetlenie:

  1. Import hooku: Importujeme vlastný hook useWindowSize.
  2. Volanie hooku: Voláme hook useWindowSize v rámci komponentu.
  3. Prístup k hodnotám: Deštrukturujeme vrátený objekt, aby sme získali hodnoty width a height.
  4. Vykreslenie hodnôt: Vykreslíme hodnoty šírky a výšky v UI komponente.

Každý komponent, ktorý používa useWindowSize, sa automaticky aktualizuje pri zmene veľkosti okna.

Zložitejšie príklady

Poďme preskúmať niektoré pokročilejšie prípady použitia vlastných hookov.

Príklad: useLocalStorage

Tento hook vám umožňuje jednoducho ukladať a načítavať dáta z lokálneho úložiska (local storage).

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  // Stav na uloženie našej hodnoty
  // Poskytnutie počiatočnej hodnoty do useState, aby sa logika vykonala iba raz
  const [storedValue, setStoredValue] = useState(() => {
    try {
      // Získanie z lokálneho úložiska podľa kľúča
      const item = window.localStorage.getItem(key);
      // Spracovanie uloženého JSONu alebo vrátenie počiatočnej hodnoty, ak žiadny nie je
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // V prípade chyby tiež vrátiť počiatočnú hodnotu
      console.log(error);
      return initialValue;
    }
  });

  // Vrátenie obalenej verzie setter funkcie z useState, ktorá...
  // ... ukladá novú hodnotu do localStorage.
  const setValue = (value) => {
    try {
      // Povolenie, aby hodnota bola funkcia, aby sme mali rovnaké API ako useState
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      // Uloženie do lokálneho úložiska
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
      // Uloženie stavu
      setStoredValue(valueToStore);
    } catch (error) {
      // Pokročilejšia implementácia by riešila chybový stav
      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;

Použitie:

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

function MyComponent() {
  const [name, setName] = useLocalStorage('name', 'Hosť');

  return (
    

Ahoj, {name}!

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

Príklad: useFetch

Tento hook zapuzdruje logiku na načítavanie dát z 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 chyba! stav: ${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;

Použitie:

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

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

  if (loading) return 

Načítava sa...

; if (error) return

Chyba: {error.message}

; return (

Názov: {data.title}

Dokončené: {data.completed ? 'Áno' : 'Nie'}

); } export default MyComponent;

Najlepšie postupy pre vlastné hooky

Aby ste zaistili, že vaše vlastné hooky sú efektívne a udržateľné, dodržiavajte tieto osvedčené postupy:

Časté nástrahy, ktorým sa treba vyhnúť

Pokročilé vzory

Skladanie vlastných hookov

Vlastné hooky sa dajú skladať dohromady a vytvárať tak zložitejšiu logiku. Napríklad by ste mohli skombinovať hook useLocalStorage s hookom useFetch na automatické ukladanie načítaných dát do lokálneho úložiska.

Zdieľanie logiky medzi hookmi

Ak viacero vlastných hookov zdieľa spoločnú logiku, môžete túto logiku extrahovať do samostatnej pomocnej funkcie a opätovne ju použiť v oboch hookoch.

Používanie Contextu s vlastnými hookmi

Vlastné hooky sa dajú použiť v spojení s React Contextom na prístup a aktualizáciu globálneho stavu. To vám umožňuje vytvárať znovupoužiteľné komponenty, ktoré sú si vedomé globálneho stavu aplikácie a môžu s ním interagovať.

Príklady z reálneho sveta

Tu sú niektoré príklady, ako sa dajú vlastné hooky použiť v reálnych aplikáciách:

Príklad: hook useGeolocation pre medzikultúrne aplikácie, ako sú mapovacie alebo doručovacie služby

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: 'Geolokácia nie je podporovaná týmto prehliadačom.',
      });
      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;

Záver

Vlastné hooky sú mocným nástrojom na písanie čistejšieho, znovupoužiteľnejšieho a udržateľnejšieho kódu v Reacte. Zapuzdrením zložitej logiky do vlastných hookov môžete zjednodušiť svoje komponenty, znížiť duplicitu kódu a zlepšiť celkovú štruktúru vašich aplikácií. Osvojte si vlastné hooky a odomknite ich potenciál na budovanie robustnejších a škálovateľnejších React aplikácií.

Začnite identifikáciou oblastí vo vašom existujúcom kóde, kde sa logika opakuje vo viacerých komponentoch. Potom túto logiku refaktorujte do vlastných hookov. Postupom času si vybudujete knižnicu znovupoužiteľných hookov, ktorá urýchli váš vývojový proces a zlepší kvalitu vášho kódu.

Nezabudnite dodržiavať osvedčené postupy, vyhýbať sa bežným nástrahám a skúmať pokročilé vzory, aby ste z vlastných hookov vyťažili maximum. S praxou a skúsenosťami sa stanete majstrom vlastných hookov a efektívnejším React vývojárom.