Odemkněte sílu znovupoužitelné logiky ve vašich React aplikacích s vlastními hooky. Naučte se, jak tvořit a využívat vlastní hooky pro čistší a udržitelnější kód.
Vlastní hooky: Vzory pro znovupoužitelnou logiku v Reactu
React hooky způsobily revoluci ve způsobu, jakým píšeme React komponenty, zavedením stavu a lifecycle funkcí do funkcionálních komponent. Mezi mnoha výhodami, které nabízejí, vynikají vlastní hooky jako mocný mechanismus pro extrakci a znovupoužití logiky napříč několika komponentami. Tento blogový příspěvek se ponoří hluboko do světa vlastních hooků, prozkoumá jejich výhody, tvorbu a použití s praktickými příklady.
Co jsou to vlastní hooky?
V podstatě je vlastní hook JavaScriptová funkce, která začíná slovem „use“ a může volat jiné hooky. Umožňují vám extrahovat logiku komponent do znovupoužitelných funkcí. Jedná se o mocný způsob sdílení stavové logiky, vedlejších efektů nebo jiného komplexního chování mezi komponentami bez nutnosti uchýlit se k render props, komponentám vyššího řádu nebo jiným složitým vzorům.
Klíčové vlastnosti vlastních hooků:
- Pojmenovací konvence: Vlastní hooky musí začínat slovem „use“. To signalizuje Reactu, že funkce obsahuje hooky a měla by dodržovat jejich pravidla.
- Znovupoužitelnost: Primárním účelem je zapouzdřit znovupoužitelnou logiku, což usnadňuje sdílení funkcionality mezi komponentami.
- Stavová logika: Vlastní hooky mohou spravovat svůj vlastní stav pomocí hooku
useState
, což jim umožňuje zapouzdřit komplexní stavové chování. - Vedlejší efekty: Mohou také provádět vedlejší efekty pomocí hooku
useEffect
, což umožňuje integraci s externími API, načítání dat a další. - Skládatelnost: Vlastní hooky mohou volat jiné hooky, což vám umožňuje vytvářet komplexní logiku skládáním menších, více zaměřených hooků.
Výhody používání vlastních hooků
Vlastní hooky nabízejí několik významných výhod ve vývoji v Reactu:
- Znovupoužitelnost kódu: Nejzřejmější výhodou je schopnost znovupoužít logiku napříč více komponentami. To snižuje duplicitu kódu a podporuje princip DRY (Don't Repeat Yourself).
- Zlepšená čitelnost: Extrakcí složité logiky do samostatných vlastních hooků se vaše komponenty stávají čistšími a snáze srozumitelnými. Jádro logiky komponenty zůstává zaměřeno na vykreslování UI.
- Zlepšená udržitelnost: Když je logika zapouzdřena ve vlastních hoocích, změny a opravy chyb lze aplikovat na jednom místě, což snižuje riziko zavlečení chyb do více komponent.
- Testovatelnost: Vlastní hooky lze snadno testovat izolovaně, což zajišťuje, že znovupoužitelná logika funguje správně nezávisle na komponentách, které ji používají.
- Zjednodušené komponenty: Vlastní hooky pomáhají uklidit komponenty, činí je méně obsáhlými a více zaměřenými na jejich primární účel.
Vytvoření vašeho prvního vlastního hooku
Pojďme si ukázat vytvoření vlastního hooku na praktickém příkladu: hook, který sleduje velikost okna.
Příklad: useWindowSize
Tento hook vrátí aktuální šířku a výšku okna prohlížeče. Také tyto hodnoty aktualizuje při změně velikosti 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);
// Odstranění posluchače událostí při úklidu
return () => window.removeEventListener('resize', handleResize);
}, []); // Prázdné pole zajišťuje, že se efekt spustí pouze při připojení (mount)
return windowSize;
}
export default useWindowSize;
Vysvětlení:
- Import nezbytných hooků: Importujeme
useState
auseEffect
z Reactu. - Definice hooku: Vytvoříme funkci s názvem
useWindowSize
, dodržujeme pojmenovací konvenci. - Inicializace stavu: Použijeme
useState
k inicializaci stavuwindowSize
s počáteční šířkou a výškou okna. - Nastavení posluchače událostí: Použijeme
useEffect
k přidání posluchače události 'resize' na okno. Když se velikost okna změní, funkcehandleResize
aktualizuje stavwindowSize
. - Úklid: Z
useEffect
vracíme úklidovou funkci pro odstranění posluchače událostí, když se komponenta odpojí. Tím se předchází únikům paměti. - Návratové hodnoty: Hook vrací objekt
windowSize
, obsahující aktuální šířku a výšku okna.
Použití vlastního hooku v komponentě
Nyní, když jsme vytvořili náš vlastní hook, podívejme se, jak ho použít v React komponentě.
import React from 'react';
import useWindowSize from './useWindowSize';
function MyComponent() {
const { width, height } = useWindowSize();
return (
Šířka okna: {width}px
Výška okna: {height}px
);
}
export default MyComponent;
Vysvětlení:
- Import hooku: Importujeme vlastní hook
useWindowSize
. - Volání hooku: V komponentě zavoláme hook
useWindowSize
. - Přístup k hodnotám: Destrukturujeme vrácený objekt, abychom získali hodnoty
width
aheight
. - Vykreslení hodnot: Vykreslíme hodnoty šířky a výšky v UI komponenty.
Jakákoli komponenta, která používá useWindowSize
, se automaticky aktualizuje při změně velikosti okna.
Složitější příklady
Pojďme prozkoumat některé pokročilejší případy použití vlastních hooků.
Příklad: useLocalStorage
Tento hook vám umožňuje snadno ukládat a načítat data z lokálního úložiště.
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
// Stav pro uložení naší hodnoty
// Předání počáteční hodnoty do useState, aby se logika provedla pouze jednou
const [storedValue, setStoredValue] = useState(() => {
try {
// Získání z lokálního úložiště podle klíče
const item = window.localStorage.getItem(key);
// Parsování uloženého JSONu, nebo vrácení initialValue, pokud nic neexistuje
return item ? JSON.parse(item) : initialValue;
} catch (error) {
// V případě chyby také vrátit initialValue
console.log(error);
return initialValue;
}
});
// Vrátí obalenou verzi setter funkce z useState, která...
// ... uloží novou hodnotu do localStorage.
const setValue = (value) => {
try {
// Povolit, aby hodnota byla funkce, takže máme stejné API jako useState
const valueToStore = value instanceof Function ? value(storedValue) : value;
// Uložení do lokálního úložiště
window.localStorage.setItem(key, JSON.stringify(valueToStore));
// Uložení stavu
setStoredValue(valueToStore);
} catch (error) {
// Pokročilejší implementace by se vypořádala s chybovým stavem
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žití:
import React from 'react';
import useLocalStorage from './useLocalStorage';
function MyComponent() {
const [name, setName] = useLocalStorage('name', 'Host');
return (
Ahoj, {name}!
setName(e.target.value)}
/>
);
}
export default MyComponent;
Příklad: useFetch
Tento hook zapouzdřuje logiku pro načítání dat 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žití:
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čítání...
;
if (error) return Chyba: {error.message}
;
return (
Název: {data.title}
Dokončeno: {data.completed ? 'Ano' : 'Ne'}
);
}
export default MyComponent;
Osvědčené postupy pro vlastní hooky
Abyste zajistili, že vaše vlastní hooky jsou efektivní a udržitelné, dodržujte tyto osvědčené postupy:
- Udržujte je zaměřené: Každý vlastní hook by měl mít jediný, dobře definovaný účel. Vyhněte se vytváření příliš složitých hooků, které se snaží dělat příliš mnoho.
- Dokumentujte své hooky: Poskytněte jasnou a stručnou dokumentaci pro každý vlastní hook, která vysvětluje jeho účel, vstupy a výstupy.
- Testujte své hooky: Pište jednotkové testy pro své vlastní hooky, abyste zajistili, že fungují správně a spolehlivě.
- Používejte popisné názvy: Vybírejte pro své vlastní hooky popisné názvy, které jasně naznačují jejich účel.
- Elegantně zpracovávejte chyby: Implementujte zpracování chyb ve svých vlastních hoocích, abyste předešli neočekávanému chování a poskytli informativní chybové zprávy.
- Myslete na znovupoužitelnost: Navrhujte své vlastní hooky s ohledem na znovupoužitelnost. Udělejte je dostatečně obecné, aby je bylo možné použít ve více komponentách.
- Vyhněte se nadměrné abstrakci: Nevytvářejte vlastní hooky pro jednoduchou logiku, kterou lze snadno zpracovat v rámci komponenty. Extrahuje pouze logiku, která je skutečně znovupoužitelná a složitá.
Časté nástrahy, kterým se vyhnout
- Porušování pravidel hooků: Vždy volejte hooky na nejvyšší úrovni vaší vlastní hook funkce a volejte je pouze z React funkcionálních komponent nebo jiných vlastních hooků.
- Ignorování závislostí v useEffect: Ujistěte se, že jste zahrnuli všechny nezbytné závislosti do pole závislostí hooku
useEffect
, abyste předešli zastaralým uzávěrům a neočekávanému chování. - Vytváření nekonečných smyček: Buďte opatrní při aktualizaci stavu v rámci hooku
useEffect
, protože to může snadno vést k nekonečným smyčkám. Zajistěte, aby byla aktualizace podmíněná a založená na změnách v závislostech. - Zapomínání na úklid: Vždy zahrňte úklidovou funkci do
useEffect
pro odstranění posluchačů událostí, zrušení odběrů a provedení dalších úklidových úkolů, abyste předešli únikům paměti.
Pokročilé vzory
Skládání vlastních hooků
Vlastní hooky lze skládat dohromady a vytvářet tak složitější logiku. Můžete například zkombinovat hook useLocalStorage
s hookem useFetch
, aby se načtená data automaticky ukládala do lokálního úložiště.
Sdílení logiky mezi hooky
Pokud více vlastních hooků sdílí společnou logiku, můžete tuto logiku extrahovat do samostatné pomocné funkce a znovu ji použít v obou hoocích.
Použití Contextu s vlastními hooky
Vlastní hooky lze použít ve spojení s React Contextem pro přístup a aktualizaci globálního stavu. To vám umožňuje vytvářet znovupoužitelné komponenty, které jsou si vědomy globálního stavu aplikace a mohou s ním interagovat.
Příklady z reálného světa
Zde je několik příkladů, jak lze vlastní hooky použít v reálných aplikacích:
- Validace formulářů: Vytvořte hook
useForm
pro zpracování stavu formuláře, validace a odeslání. - Autentizace: Implementujte hook
useAuth
pro správu autentizace a autorizace uživatelů. - Správa témat: Vyviňte hook
useTheme
pro přepínání mezi různými tématy (světlé, tmavé atd.). - Geolokace: Vytvořte hook
useGeolocation
pro sledování aktuální polohy uživatele. - Detekce rolování: Vytvořte hook
useScroll
pro detekci, kdy uživatel doroloval na určitý bod na stránce.
Příklad: hook useGeolocation pro mezikulturní aplikace, jako jsou mapovací nebo doručovací 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: 'Geolokace není tímto prohlížečem podporována.',
});
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ávěr
Vlastní hooky jsou mocným nástrojem pro psaní čistšího, znovupoužitelnějšího a lépe udržitelného kódu v Reactu. Zapouzdřením složité logiky do vlastních hooků můžete zjednodušit své komponenty, snížit duplicitu kódu a zlepšit celkovou strukturu vašich aplikací. Přijměte vlastní hooky a odemkněte jejich potenciál pro vytváření robustnějších a škálovatelnějších React aplikací.
Začněte identifikací oblastí ve vašem stávajícím kódu, kde se logika opakuje napříč více komponentami. Poté tuto logiku refaktorujte do vlastních hooků. Postupem času si vybudujete knihovnu znovupoužitelných hooků, která zrychlí váš vývojový proces a zlepší kvalitu vašeho kódu.
Nezapomeňte dodržovat osvědčené postupy, vyhýbat se běžným nástrahám a prozkoumávat pokročilé vzory, abyste z vlastních hooků vytěžili co nejvíce. S praxí a zkušenostmi se stanete mistrem vlastních hooků a efektivnějším vývojářem v Reactu.