2023-10-18 14:15 Doba čtení: 10 min

Srovnání háčků pro získávání dat v Reactu

React háky představují efektivní nástroj pro správu vedlejších efektů v rámci komponent React. Mezi nejběžnější háky pro práci s těmito efekty patří `useEffect`, `useLayoutEffect` a `useEffectEvent`. Každý z nich má specifické využití, proto je klíčové zvolit ten správný pro daný úkol.

Háček UseEffect

Háček `useEffect` je základním prvkem v Reactu, který umožňuje provádět vedlejší efekty, jako je manipulace s DOM, asynchronní operace nebo načítání dat, uvnitř funkčních komponent. Tento háček je definován jako funkce, která přijímá dva parametry: funkci efektu a pole závislostí.

Funkce efektu obsahuje kód, který provádí vedlejší efekt, a pole závislostí určuje, kdy se má funkce efektu spustit. Pokud je pole závislostí prázdné, funkce efektu se spustí pouze jednou, a to při prvním vykreslení komponenty. V opačném případě se funkce efektu aktivuje vždy, když dojde ke změně některé z hodnot v poli závislostí.

Následuje příklad použití háčku `useEffect` pro načtení dat:

 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;

Tento kód ukazuje komponentu `App`, která za pomoci háčku `useEffect` načítá data z externího API. Funkce efektu uvnitř `useEffect` načítá data z API JSONPlaceholder. Po získání odpovědi ve formátu JSON se načtená data uloží do stavu komponenty.

S využitím stavu `data` komponenta `App` následně vykreslí titulek (`title`) každé položky.

Charakteristika háku useEffect

  • Podpora asynchronních operací: Umožňuje nativně pracovat s asynchronními operacemi, což ho činí vhodným pro načítání dat.
  • Spuštění po vykreslení: Efekty uvnitř háku `useEffect` se spouští až po vykreslení komponenty, čímž se zajišťuje, že nedojde k zablokování uživatelského rozhraní.
  • Možnost úklidu: Poskytuje zabudovaný mechanismus pro provádění úklidových operací pomocí návratové funkce. To se hodí zejména při práci s odběry událostí.

Háček UseLayoutEffect

Háček `useLayoutEffect` je podobný `useEffect`, ale probíhá synchronně po všech mutacích DOM. To znamená, že se spustí dříve, než prohlížeč vykreslí obrazovku, což ho činí ideálním pro úkoly, které vyžadují přesnou kontrolu nad rozložením a styly DOM. Typickými příklady jsou měření velikosti prvků, jejich změna nebo animace pozice.

Následující příklad ukazuje, jak lze `useLayoutEffect` použít pro změnu šířky tlačítka:

 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;

Tento kód zvětší šířku tlačítka o 12 pixelů s využitím háčku `useLayoutEffect`. Díky tomu se zajistí, že se šířka tlačítka zvětší před jeho zobrazením na obrazovce.

Charakteristika háku useLayoutEffect

  • Synchronní provedení: Provádí se synchronně, což může potenciálně blokovat uživatelské rozhraní, pokud jsou operace v něm náročné.
  • Čtení/zápis DOM: Je nejvhodnější pro operace, které přímo čtou z DOM nebo do něj zapisují, zejména pokud jsou změny potřeba před překreslením prohlížeče.

Háček UseEffectEvent

Háček `useEffectEvent` řeší problémy se závislostmi háku `useEffect`. Jak je známo, pole závislostí u `useEffect` může být problematické. Někdy je nutné do pole závislostí zahrnout hodnoty, které tam nutně být nemusejí.

Například:

 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;

Tento kód ukazuje komponentu `App`, která spravuje připojení k externí službě. Funkce `connect` naváže připojení k zadané adrese URL a `logConnection` zaznamená detaily o připojení. Funkce `onConnected` volá `logConnection`, aby zaznamenala zprávu o úspěšném připojení.

Háček `useEffect` volá funkci `connect` a nastaví zpětné volání `onConnected`, které se spustí při události `onConnected` zařízení. Toto zpětné volání pak zaznamená zprávu o připojení. Funkce vrací i čistící funkci, která se volá při odpojení komponenty a odpojí zařízení.

Pole závislostí obsahuje proměnnou `url` a funkci `onConnected`. Při každém vykreslení se vytvoří nová funkce `onConnected`. To vede k tomu, že `useEffect` běží v nekonečné smyčce, což způsobuje opakované vykreslování komponenty.

Problém nekonečné smyčky v `useEffect` má několik řešení. Nejefektivnější, aniž bychom museli přidávat zbytečné hodnoty do pole závislostí, je použití háku `useEffectEvent`.

 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;

Tím, že obalíme funkci `onConnected` do `useEffectEvent`, zajistíme, že `useEffectEvent` vždy přečte nejnovější hodnoty parametrů `message` a `loginOptions` před tím, než je předá do `useEffect`. To znamená, že `useEffect` se nemusí spoléhat na funkci `onConnected` nebo hodnoty, které jí předává.

`useEffectEvent` se hodí, pokud chceme, aby `useEffect` závisel na konkrétní hodnotě, i když efekt spouští událost, která vyžaduje další hodnoty, které nechceme v `useEffect` používat jako závislosti.

Charakteristika háku useEffectEvent

  • Vhodný pro vedlejší efekty spouštěné událostmi.
  • `useEffectEvent` nefunguje s obslužnými rutinami událostí jako jsou `onClick` nebo `onChange`.

Háček `useEffectEvent` je stále v experimentální fázi a není dostupný v Reactu verze 18.

Kdy který háček použít?

Každý z výše uvedených háků je vhodný pro různé situace:

  • Načítání dat: `UseEffect` je vynikající volbou.
  • Přímé manipulace s DOM: Pokud potřebujete provádět synchronní změny DOM před vykreslením, zvolte `useLayoutEffect`.
  • Odlehčené operace: Pro operace, které neblokují uživatelské rozhraní, je `useEffect` vhodný.
  • Vedlejší efekty řízené událostmi: Použijte `useEffectEvent` pro obalení událostí a `useEffect` pro spuštění vedlejších efektů.

Efektivní řešení vedlejších efektů

React háky otevírají široké možnosti a pochopení rozdílů mezi háky `useEffect`, `useLayoutEffect` a `useEffectEvent` může výrazně ovlivnit způsob, jakým pracujete s vedlejšími efekty a manipulací s DOM. Je důležité zvážit specifické požadavky a důsledky těchto háků pro vytvoření uživatelsky přívětivých aplikací.

Jan Novák
Autor
Czechia

Redaktor zaměřený na Windows, produktivitu a cloudové nástroje.

Předchozí článek
Jak nástroje pro cloudovou spolupráci přetvářejí podniky [25 Tools Discussed]
Další článek
8 streamovacích služeb, které stále umožňují sdílení hesel