React Hooks: Kompletny przewodnik dla początkujących

React Hooks zrewolucjonizowały sposób pisania aplikacji React. Od wprowadzenia w wersji 16.8, pozwalają nam na używanie stanu i innych funkcji React bez konieczności pisania komponentów klasowych. W tym artykule przeprowadzimy Cię przez najważniejsze hooki krok po kroku.

Czym są React Hooks?

Hooks to funkcje, które pozwalają "podłączyć się" do mechanizmów React z poziomu komponentów funkcyjnych. Nazwą nawiązują do "zahaczania się" o funkcjonalności React takie jak zarządzanie stanem czy efekty uboczne.

Zalety React Hooks:

useState - Zarządzanie stanem

useState to podstawowy hook, który pozwala dodać stan lokalny do komponentu funkcyjnego. Zwraca tablicę z dwoma elementami: obecną wartością stanu oraz funkcją do jego aktualizacji.

import React, { useState } from 'react'; function Counter() { // Deklaracja zmiennej stanu "count" z początkową wartością 0 const [count, setCount] = useState(0); return ( <div> <p>Kliknięto: {count} razy</p> <button onClick={() => setCount(count + 1)}> Kliknij mnie </button> </div> ); }

Ważna zasada

Hooks można używać tylko na najwyższym poziomie komponentów funkcyjnych. Nie można ich wywoływać wewnątrz pętli, warunków czy zagnieżdżonych funkcji.

useEffect - Efekty uboczne

useEffect pozwala wykonywać efekty uboczne w komponentach funkcyjnych. Jest odpowiednikiem componentDidMount, componentDidUpdate i componentWillUnmount połączonych w jedną API.

import React, { useState, useEffect } from 'react'; function UserProfile({ userId }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { // Funkcja do pobierania danych użytkownika const fetchUser = async () => { setLoading(true); try { const response = await fetch(`/api/users/${userId}`); const userData = await response.json(); setUser(userData); } catch (error) { console.error('Błąd podczas pobierania użytkownika:', error); } finally { setLoading(false); } }; fetchUser(); }, [userId]); // Efekt uruchomi się ponownie gdy userId się zmieni if (loading) return <div>Ładowanie...</div>; return ( <div> <h2>{user?.name}</h2> <p>{user?.email}</p> </div> ); }

Tablica zależności

Drugi parametr useEffect to tablica zależności. Określa ona, kiedy efekt powinien zostać uruchomiony ponownie:

useContext - Konsumowanie kontekstu

useContext pozwala na łatwiejsze korzystanie z React Context API. Elimina potrzebę zagnieżdżania komponentów w Consumer.

import React, { createContext, useContext, useState } from 'react'; // Tworzymy kontekst dla motywu const ThemeContext = createContext(); // Dostawca motywu function ThemeProvider({ children }) { const [theme, setTheme] = useState('light'); const toggleTheme = () => { setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light'); }; return ( <ThemeContext.Provider value={{ theme, toggleTheme }}> {children} </ThemeContext.Provider> ); } // Komponent używający kontekstu function Header() { const { theme, toggleTheme } = useContext(ThemeContext); return ( <header style={{ backgroundColor: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#333' : '#fff' }}> <h1>Moja aplikacja</h1> <button onClick={toggleTheme}> Przełącz na {theme === 'light' ? 'ciemny' : 'jasny'} motyw </button> </header> ); }

Własne hooki (Custom Hooks)

Jedną z największych zalet hooks jest możliwość tworzenia własnych, wielokrotnego użytku hooków, które enkapsulują logikę biznesową.

import { useState, useEffect } from 'react'; // Własny hook do pobierania danych function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { setLoading(true); setError(null); const response = await fetch(url); if (!response.ok) { throw new Error('Błąd sieci'); } const result = await response.json(); setData(result); } catch (err) { setError(err.message); } finally { setLoading(false); } }; fetchData(); }, [url]); return { data, loading, error }; } // Użycie własnego hooka function ProductList() { const { data: products, loading, error } = useFetch('/api/products'); if (loading) return <div>Ładowanie produktów...</div>; if (error) return <div>Błąd: {error}</div>; return ( <ul> {products?.map(product => ( <li key={product.id}>{product.name}</li> ))} </ul> ); }

Najlepsze praktyki

1. Nazwij własne hooki z prefiksem "use"

To konwencja, która pomoże narzędziom deweloperskim rozpoznać hooki i zastosować odpowiednie reguły.

2. Używaj eslint-plugin-react-hooks

Ten plugin pomoże Ci uniknąć powszechnych błędów związanych z hookami.

3. Optymalizuj wydajność

Używaj useMemo i useCallback do optymalizacji kosztownych obliczeń i funkcji.

Podsumowanie

React Hooks to potężne narzędzie, które upraszcza pisanie komponentów React. Zaczynaj od podstawowych hooks jak useState i useEffect, a następnie eksploruj bardziej zaawansowane możliwości. Pamiętaj o regułach hooks i twórz własne hooki do enkapsulacji logiki biznesowej.

Hooks otworzyły nową erę w rozwoju React, czyniąc kod bardziej funkcyjnym, czytelnym i łatwiejszym do testowania. Z praktyką stania się naturalną częścią Twojego warsztatu programistycznego.

← Powrót do bloga