Why Hooks?
Hooks let you use state and lifecycle features in function components. They replaced class components as the recommended approach in React.
useState — Managing State
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)}>+1</button>
</div>
);
}
useEffect — Side Effects
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
async function fetchUser() {
setLoading(true);
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
if (!cancelled) setUser(data);
setLoading(false);
}
fetchUser();
return () => { cancelled = true; };
}, [userId]);
if (loading) return <Spinner />;
return <div>{user?.name}</div>;
}
useRef — References
function TextInput() {
const inputRef = useRef(null);
const focusInput = () => inputRef.current?.focus();
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus</button>
</div>
);
}
useMemo and useCallback — Performance
function ProductList({ products, filter }) {
const filtered = useMemo(() =>
products.filter(p => p.name.includes(filter)),
[products, filter]
);
const handleAdd = useCallback((product) => {
dispatch({ type: 'ADD', payload: product });
}, []);
return <List items={filtered} onAdd={handleAdd} />;
}
useReducer — Complex State
function todoReducer(state, action) {
switch (action.type) {
case 'ADD':
return [...state, { id: Date.now(), text: action.text, done: false }];
case 'TOGGLE':
return state.map(t => t.id === action.id ? { ...t, done: !t.done } : t);
case 'DELETE':
return state.filter(t => t.id !== action.id);
default:
return state;
}
}
Custom Hooks
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored !== null ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}