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í.