A React Hooks forradalmasították a React komponensek írását. Ebben az átfogó útmutatóban megtanulod, hogyan használd a Hooks-okat nulláról, gyakorlati példákkal és best practice-ekkel.
Mi az a Hook?
A Hooks olyan függvények, amelyek lehetővé teszik, hogy "beakasztsd magad" a React funkcióiba funkcionális komponensekből. Korábban csak class komponensekben lehetett state-t és lifecycle metódusokat használni - most már funkcionális komponensekben is!
Miért használjunk Hooks-okat?
- 🎯 Egyszerűbb kód: Kevesebb boilerplate, olvashatóbb logika
- ♻️ Kód újrafelhasználás: Custom Hooks-okkal könnyen megoszthatjuk a logikát
- 🧩 Jobb szervezés: Kapcsolódó logika egy helyen marad
- ⚡ Könnyebb tesztelés: Funkcionális komponensek egyszerűbben tesztelhetők
1. useState - Állapotkezelés
A useState a legalapvetőbb Hook. Lehetővé teszi, hogy state-t adj hozzá
funkcionális komponensedhez:
Egyszerű példa:
import { useState } from 'react';
function Counter() {
// [state változó, frissítő függvény] = useState(kezdőérték)
const [count, setCount] = useState(0);
return (
<div>
<p>Számláló: {count}</p>
<button onClick={() => setCount(count + 1)}>
Növel
</button>
<button onClick={() => setCount(count - 1)}>
Csökkent
</button>
<button onClick={() => setCount(0)}>
Reset
</button>
</div>
);
}
Összetett state:
function UserProfile() {
const [user, setUser] = useState({
name: '',
email: '',
age: 0
});
const updateName = (newName) => {
setUser({
...user, // Spread operátor - megtartjuk a többi értéket
name: newName // Csak a name-et frissítjük
});
};
return (
<input
value={user.name}
onChange={(e) => updateName(e.target.value)}
/>
);
}
Funkcionális frissítés:
function Counter() {
const [count, setCount] = useState(0);
const incrementTwice = () => {
// ❌ Ez NEM fog 2-vel növelni
setCount(count + 1);
setCount(count + 1);
// ✅ Ez IGEN
setCount(prev => prev + 1);
setCount(prev => prev + 1);
};
return <button onClick={incrementTwice}>+2</button>;
}
2. useEffect - Mellékhatások kezelése
A useEffect lehetővé teszi mellékhatások (side effects) végrehajtását
komponenseidben. Példák: adatbetöltés, DOM manipuláció, feliratkozások.
Alapvető használat:
import { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Ez a kód minden render után lefut
fetch('/api/users')
.then(res => res.json())
.then(data => {
setUsers(data);
setLoading(false);
});
}, []); // Üres dependency array = csak mountoláskor fut
if (loading) return <p>Töltés...</p>;
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
Dependency array:
function SearchResults({ query }) {
const [results, setResults] = useState([]);
useEffect(() => {
// Csak akkor fut, ha a query megváltozik
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(setResults);
}, [query]); // query a dependency
return <ResultsList results={results} />;
}
Cleanup funkció:
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(s => s + 1);
}, 1000);
// Cleanup: komponens unmountkor fut
return () => clearInterval(interval);
}, []);
return <div>Eltelt idő: {seconds} másodperc</div>;
}
3. useContext - Kontextus használata
A useContext lehetővé teszi, hogy komponensek között prop drilling nélkül
oszd meg az adatokat:
import { createContext, useContext, useState } from 'react';
// Kontextus létrehozása
const ThemeContext = createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return <ThemeButton />;
}
function ThemeButton() {
// Kontextus használata
const { theme, setTheme } = useContext(ThemeContext);
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Jelenlegi téma: {theme}
</button>
);
}
4. useReducer - Komplex state kezelés
A useReducer a useState alternatívája összetett state
logikához:
import { useReducer } from 'react';
// Reducer függvény
function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM':
return {
...state,
items: [...state.items, action.payload]
};
case 'REMOVE_ITEM':
return {
...state,
items: state.items.filter(item => item.id !== action.payload)
};
case 'CLEAR_CART':
return { ...state, items: [] };
default:
return state;
}
}
function ShoppingCart() {
const [cart, dispatch] = useReducer(cartReducer, { items: [] });
const addItem = (item) => {
dispatch({ type: 'ADD_ITEM', payload: item });
};
return (
<div>
<button onClick={() => addItem({ id: 1, name: 'Termék' })}>
Hozzáad
</button>
<button onClick={() => dispatch({ type: 'CLEAR_CART' })}>
Kosár ürítése
</button>
</div>
);
}
5. useRef - Referenciák kezelése
A useRef lehetővé teszi DOM elemek elérését és megváltozhatatlan értékek
tárolását:
import { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// Automatikus focus mountoláskor
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
// Renderelés számának követése
function RenderCounter() {
const renderCount = useRef(0);
useEffect(() => {
renderCount.current += 1;
});
return <p>Renderelések száma: {renderCount.current}</p>;
}
6. useMemo és useCallback - Optimalizálás
Ezek a Hooks segítenek a teljesítmény optimalizálásában:
useMemo - Értékek memoizálása:
import { useMemo } from 'react';
function ExpensiveComponent({ data }) {
// Ez a számítás csak akkor fut újra, ha data változik
const sortedData = useMemo(() => {
console.log('Expensive sorting...');
return data.sort((a, b) => a.value - b.value);
}, [data]);
return <DataList data={sortedData} />;
}
useCallback - Függvények memoizálása:
import { useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
// Ez a függvény csak egyszer jön létre
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<ChildComponent onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
</div>
);
}
Custom Hooks - Saját Hooks készítése
A legjobb dolog a Hooks-okban: létrehozhatod a sajátokat!
// useLocalStorage custom hook
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
// Használat
function App() {
const [name, setName] = useLocalStorage('username', '');
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}
Még egy példa - useFetch:
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(err => {
setError(err);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}
// Használat
function UserProfile({ userId }) {
const { data, loading, error } = useFetch(`/api/users/${userId}`);
if (loading) return <p>Töltés...</p>;
if (error) return <p>Hiba: {error.message}</p>;
return <div>{data.name}</div>;
}
Hooks szabályok
A Hooks használatához be kell tartani két fontos szabályt:
- ✅ Csak a legfelső szinten hívd őket - nem ciklusokban, feltételekben vagy nested függvényekben
- ✅ Csak React függvényekből hívd őket - funkcionális komponensekből vagy custom Hooks-okból
// ❌ ROSSZ
function Component() {
if (condition) {
useState(0); // NE!
}
}
// ✅ JÓ
function Component() {
const [value, setValue] = useState(0);
if (condition) {
setValue(10); // OK!
}
}
Best Practices
- Használj ESLint plugin-t:
eslint-plugin-react-hooks - Ne felejtsd el a dependency array-t a useEffect-ben
- Custom Hooks-okat mindig
useprefixszel nevezz el - Ne túlozd el a memoizálást - csak ha valóban szükséges
- Tartsd egyszerűnek a komponenseket - ha túl komplex, bontsd kisebbekre
Összegzés
A React Hooks modern, hatékony módot kínálnak a React komponensek írására. A
useState és useEffect az alapok, de a többi Hook és a
custom Hooks valódi szupererőket adnak.
A legjobb módszer a tanulásra: gyakorlás! Kezdj el Hooks-okat használni a projektjeidben, kísérletezz, és hamarosan természetessé válik. Hajrá!