Поређење кукица за преузимање података у Реацт-у

React hookovi predstavljaju snažan mehanizam za upravljanje bočnim efektima unutar React komponenti. Tri najčešće korišćena hooka za rad s ovim efektima su useEffect, useLayoutEffect i useEffectEvent. Svaki od njih ima specifičnu primenu, što čini odabir odgovarajućeg ključnim za efikasan razvoj.

useEffect Hook

useEffect hook je fundamentalni alat u Reactu koji omogućava izvršavanje bočnih efekata, poput manipulacije DOM-om, asinhronih operacija i preuzimanja podataka, unutar funkcionalnih komponenti. Ovaj hook je zapravo funkcija koja prima dva argumenta: funkciju efekta i niz zavisnosti.

Funkcija efekta sadrži kod koji se izvršava kao bočni efekat, dok niz zavisnosti određuje kada će se ta funkcija pokrenuti. Ako je niz zavisnosti prazan, funkcija efekta se izvršava samo jednom, pri prvom renderovanju komponente. U suprotnom, funkcija efekta se ponovo pokreće svaki put kada se promeni vrednost neke od zavisnosti.

Sledi primer kako koristiti useEffect hook za preuzimanje podataka:

 import React from "react";

function App() {
  const [data, setData] = React.useState([]);

  React.useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return (
    <div className="app">
      {data.map((item) => (
        <div key={item.id}>{item.title}</div>
      ))}
    </div>
  );
}

export default App;

Ovaj kod prikazuje komponentu aplikacije koja, koristeći useEffect hook, preuzima podatke iz spoljnog API-ja. Funkcija efekta unutar useEffect-a dohvaća podatke sa JSONPlaceholder API-ja. Zatim se JSON odgovor parsira i preuzeti podaci se postavljaju u stanje pod nazivom „data“.

Sa ovim stanjem, komponenta aplikacije prikazuje svojstvo „title“ svake stavke iz stanja.

Karakteristike useEffect Hook-a

  • Pogodan za asinhrono: inherentno podržava asinhrone operacije, što ga čini pogodnim za dohvat podataka.
  • Izvršava se nakon renderovanja: useEffect hook izvršava efekte nakon što aplikacija renderuje komponentu, čime se osigurava da hook ne blokira korisnički interfejs.
  • Čišćenje: pruža ugrađen način za obavljanje čišćenja vraćanjem funkcije. Ovo je posebno korisno pri radu sa slušaocima ili pretplatama.

useLayoutEffect Hook

useLayoutEffect hook je sličan useEffect hooku, ali se izvršava sinhrono, neposredno nakon svih DOM mutacija. To znači da se pokreće pre nego što pregledač iscrta ekran, što ga čini idealnim za zadatke koji zahtevaju preciznu kontrolu nad DOM izgledom i stilovima, kao što su merenje dimenzija elementa, promena veličine elementa ili animacija njegove pozicije.

Sledi primer kako koristiti useLayoutEffect hook za promenu širine dugmeta:

 import React from "react";

function App() {
  const button = React.useRef();

  React.useLayoutEffect(() => {
    const { width } = button.current.getBoundingClientRect();

    button.current.style.width = `${width + 12}px`;
  }, []);

  return (
    <div className="app">
      <button ref={button}>Click Me</button>
    </div>
  );
}

export default App;

Gornji blok koda povećava širinu dugmeta za 12 piksela koristeći useLayoutEffect hook. Ovo osigurava da se širina dugmeta poveća pre nego što se samo dugme prikaže na ekranu.

Karakteristike useLayoutEffect Hook-a

  • Sinhrono: izvršava se sinhrono, potencijalno blokirajući korisnički interfejs ako je operacija unutar njega teška.
  • DOM čitanje/pisanje: najprikladniji je za direktno čitanje i pisanje u DOM-u, posebno ako su vam potrebne promene pre nego što pregledač ponovo iscrta.

useEffectEvent Hook

useEffectEvent hook je React hook koji rešava probleme sa zavisnostima u useEffect hooku. Ako ste upoznati sa useEffect-om, znate da njegov niz zavisnosti može biti izazovan. Ponekad morate dodati više vrednosti u taj niz, iako one nisu striktno neophodne.

Na primer:

 import React from "react";

function App() {
  const connect = (url) => {
    
  };

  const logConnection = (message, loginOptions) => {
    
  };

  const onConnected = (url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  };

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url, onConnected]);

  return <div></div>;
}

export default App;

Ovaj kod prikazuje komponentu aplikacije koja upravlja vezom sa spoljnom uslugom. Funkcija „connect“ se povezuje na određeni URL, dok funkcija „logConnection“ evidentira detalje veze. Konačno, funkcija „onConnected“ poziva funkciju „logConnection“ da evidentira poruku o uspešnoj vezi kada se uređaj poveže.

useEffect hook poziva funkciju povezivanja, a zatim postavlja „onConnected“ povratni poziv koji se izvršava kada uređaj pokrene „onConnected“ događaj. Ovaj povratni poziv evidentira poruku o vezi. Vraća se i funkcija čišćenja koja se aktivira kada se komponenta isključi. Ova funkcija čišćenja je odgovorna za isključivanje uređaja.

Niz zavisnosti sadrži promenljivu „url“ i funkciju „onConnected“. Komponenta aplikacije će kreirati novu funkciju „onConnected“ pri svakom renderovanju. Ovo će uzrokovati da se useEffect funkcija pokreće u petlji, što će neprekidno ponovo renderovati komponentu aplikacije.

Postoji nekoliko načina da se reši problem useEffect petlje. Ipak, najefikasniji način da to uradite bez dodavanja suvišnih vrednosti u niz zavisnosti je upotreba useEffectEvent hooka.

 import React from "react";

function App() {
  const connect = (url) => {
    
  };

  const logConnection = (message, loginOptions) => {
    
  };

  const onConnected = React.useEffectEvent((url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  });

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url]);

  return <div></div>;
}
export default App;

Omotavanjem funkcije „onConnected“ useEffectEvent hookom, ovaj hook uvek može pročitati najnovije vrednosti parametara „message“ i „loginOptions“ pre nego što ih prosledi u useEffect hook. To znači da useEffect ne mora da se oslanja na „onConnected“ funkciju ili vrednosti koje su joj prosleđene.

useEffectEvent hook je koristan kada želite da vaš useEffect zavisi od određene vrednosti, iako efekat pokreće događaj koji zahteva druge vrednosti koje ne želite da koristite kao zavisnosti u useEffect-u.

Karakteristike useEffectEvent Hook-a

  • Najprikladniji je za bočne efekte vođene događajima.
  • useEffectEvent hook ne funkcioniše sa rukovaocima događaja kao što su onClick, onChange, itd.

useEffectEvent hook je još uvek eksperimentalan i nije dostupan u React verziji 18 hookova.

Kada koristiti koji hook?

Svaki od gore navedenih hookova za preuzimanje podataka je pogodan za različite situacije:

  • Dohvat podataka: useEffect je odličan izbor.
  • Direktna manipulacija DOM-om: ako treba da izvršite sinhronu promenu u DOM-u pre ponovnog crtanja, koristite useLayoutEffect.
  • Jednostavne operacije: za operacije koje ne rizikuju blokiranje korisničkog interfejsa, možete bez problema koristiti useEffect.
  • Bočni efekti vođeni događajima: koristite useEffectEvent hook za umotavanje događaja i useEffect hook za pokretanje bočnih efekata.

Efikasno tretiranje bočnih efekata

React hookovi otvaraju vrata ka svetu mogućnosti, a razumevanje razlike između hookova useEffect, useLayoutEffect i useEffectEvent može značajno uticati na način na koji se nosite sa bočnim efektima i DOM manipulacijom. Neophodno je uzeti u obzir specifične zahteve i implikacije ovih hookova kako bi se kreirale aplikacije prilagođene korisniku.