Hrvatski

Otključajte snagu višekratno upotrebljive logike u svojim React aplikacijama s prilagođenim hookovima. Naučite kako stvoriti i koristiti prilagođene hookove za čišći i održiviji kod.

Prilagođeni Hookovi: Obrasci za Višekratnu Upotrebu Logike u Reactu

React Hookovi su revolucionirali način na koji pišemo React komponente uvođenjem stanja i životnog ciklusa u funkcijske komponente. Među mnogim prednostima koje nude, prilagođeni hookovi ističu se kao moćan mehanizam za izdvajanje i ponovnu upotrebu logike u više komponenti. Ovaj blog post će se detaljno baviti svijetom prilagođenih hookova, istražujući njihove prednosti, stvaranje i upotrebu s praktičnim primjerima.

Što su Prilagođeni Hookovi?

U suštini, prilagođeni hook je JavaScript funkcija koja počinje s riječju "use" i može pozivati druge hookove. Omogućuju vam izdvajanje logike komponente u funkcije za višekratnu upotrebu. Ovo je moćan način za dijeljenje logike sa stanjem, nuspojava ili drugih složenih ponašanja između komponenti bez pribjegavanja render props, komponentama višeg reda (higher-order components) ili drugim složenim obrascima.

Ključne Karakteristike Prilagođenih Hookova:

Prednosti Korištenja Prilagođenih Hookova

Prilagođeni hookovi nude nekoliko značajnih prednosti u React razvoju:

Stvaranje Vašeg Prvog Prilagođenog Hooka

Ilustrirajmo stvaranje prilagođenog hooka praktičnim primjerom: hook koji prati veličinu prozora preglednika.

Primjer: useWindowSize

Ovaj hook će vratiti trenutnu širinu i visinu prozora preglednika. Također će ažurirati te vrijednosti kada se prozor promijeni.

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

    // Ukloni event listener pri čišćenju
    return () => window.removeEventListener('resize', handleResize);
  }, []); // Prazan niz osigurava da se efekt pokrene samo pri montiranju

  return windowSize;
}

export default useWindowSize;

Objašnjenje:

  1. Uvoz Potrebnih Hookova: Uvozimo useState i useEffect iz Reacta.
  2. Definiranje Hooka: Stvaramo funkciju nazvanu useWindowSize, pridržavajući se konvencije o imenovanju.
  3. Inicijalizacija Stanja: Koristimo useState za inicijalizaciju stanja windowSize s početnom širinom i visinom prozora.
  4. Postavljanje Event Listenera: Koristimo useEffect za dodavanje event listenera za promjenu veličine (resize) na prozor. Kada se prozor promijeni, funkcija handleResize ažurira stanje windowSize.
  5. Čišćenje: Vraćamo funkciju za čišćenje iz useEffect kako bismo uklonili event listener kada se komponenta demontira. Time se sprječavaju curenja memorije.
  6. Povratne Vrijednosti: Hook vraća objekt windowSize, koji sadrži trenutnu širinu i visinu prozora.

Korištenje Prilagođenog Hooka u Komponenti

Sada kada smo stvorili naš prilagođeni hook, pogledajmo kako ga koristiti u React komponenti.

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

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

  return (
    

Širina prozora: {width}px

Visina prozora: {height}px

); } export default MyComponent;

Objašnjenje:

  1. Uvoz Hooka: Uvozimo prilagođeni hook useWindowSize.
  2. Poziv Hooka: Pozivamo hook useWindowSize unutar komponente.
  3. Pristup Vrijednostima: Destrukturiramo vraćeni objekt kako bismo dobili vrijednosti width i height.
  4. Renderiranje Vrijednosti: Renderiramo vrijednosti širine i visine u korisničkom sučelju komponente.

Svaka komponenta koja koristi useWindowSize automatski će se ažurirati kada se veličina prozora promijeni.

Složeniji Primjeri

Istražimo neke naprednije slučajeve upotrebe prilagođenih hookova.

Primjer: useLocalStorage

Ovaj hook vam omogućuje jednostavno pohranjivanje i dohvaćanje podataka iz lokalne pohrane (local storage).

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  // Stanje za pohranu naše vrijednosti
  // Proslijedi početnu vrijednost u useState kako bi se logika izvršila samo jednom
  const [storedValue, setStoredValue] = useState(() => {
    try {
      // Dohvati iz lokalne pohrane po ključu
      const item = window.localStorage.getItem(key);
      // Parsiraj pohranjeni JSON ili vrati početnu vrijednost ako ne postoji
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // Ako dođe do greške, također vrati početnu vrijednost
      console.log(error);
      return initialValue;
    }
  });

  // Vrati omotanu verziju useState setter funkcije koja...
  // ... pohranjuje novu vrijednost u localStorage.
  const setValue = (value) => {
    try {
      // Dopusti da vrijednost bude funkcija kako bismo imali isti API kao useState
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      // Spremi u lokalnu pohranu
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
      // Spremi stanje
      setStoredValue(valueToStore);
    } catch (error) {
      // Naprednija implementacija bi obradila slučaj greške
      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;

Upotreba:

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

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

  return (
    

Pozdrav, {name}!

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

Primjer: useFetch

Ovaj hook enkapsulira logiku za dohvaćanje podataka s API-ja.

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 greška! status: ${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;

Upotreba:

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

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

  if (loading) return 

Učitavanje...

; if (error) return

Greška: {error.message}

; return (

Naslov: {data.title}

Završeno: {data.completed ? 'Da' : 'Ne'}

); } export default MyComponent;

Najbolje Prakse za Prilagođene Hookove

Kako biste osigurali da su vaši prilagođeni hookovi učinkoviti i održivi, slijedite ove najbolje prakse:

Uobičajene Zamke koje Treba Izbjegavati

Napredni Obrasci

Sastavljanje Prilagođenih Hookova

Prilagođeni hookovi mogu se sastavljati zajedno kako bi se stvorila složenija logika. Na primjer, mogli biste kombinirati useLocalStorage hook s useFetch hookom kako biste automatski pohranili dohvaćene podatke u lokalnu pohranu.

Dijeljenje Logike Između Hookova

Ako više prilagođenih hookova dijeli zajedničku logiku, možete tu logiku izdvojiti u zasebnu pomoćnu funkciju i ponovno je koristiti u oba hooka.

Korištenje Konteksta s Prilagođenim Hookovima

Prilagođeni hookovi mogu se koristiti zajedno s React Contextom za pristup i ažuriranje globalnog stanja. To vam omogućuje stvaranje višekratno upotrebljivih komponenti koje su svjesne globalnog stanja aplikacije i mogu s njim komunicirati.

Primjeri iz Stvarnog Svijeta

Evo nekoliko primjera kako se prilagođeni hookovi mogu koristiti u stvarnim aplikacijama:

Primjer : useGeolocation hook za multikulturalne aplikacije poput kartografskih ili dostavnih usluga

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: 'Geolokacija nije podržana u ovom pregledniku.',
      });
      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;

Zaključak

Prilagođeni hookovi su moćan alat za pisanje čišćeg, višekratno upotrebljivog i održivijeg React koda. Enkapsulacijom složene logike u prilagođene hookove, možete pojednostaviti svoje komponente, smanjiti dupliciranje koda i poboljšati cjelokupnu strukturu svojih aplikacija. Prihvatite prilagođene hookove i otključajte njihov potencijal za izgradnju robusnijih i skalabilnijih React aplikacija.

Počnite identificiranjem područja u vašem postojećem kodu gdje se logika ponavlja u više komponenti. Zatim, refaktorirajte tu logiku u prilagođene hookove. S vremenom ćete izgraditi biblioteku višekratno upotrebljivih hookova koji će ubrzati vaš proces razvoja i poboljšati kvalitetu vašeg koda.

Ne zaboravite slijediti najbolje prakse, izbjegavati uobičajene zamke i istraživati napredne obrasce kako biste maksimalno iskoristili prilagođene hookove. S praksom i iskustvom, postat ćete majstor prilagođenih hookova i učinkovitiji React programer.