useState
Manages local component state.
const [isOpen, setIsOpen] = useState(false);
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
useEffect
Runs side effects — fetch, subscriptions, timers.
useEffect(() => {
fetch('/api/trades').then(r => r.json()).then(setTrades);
}, []); // empty array = run once on mount
useEffect(() => {
// runs every time userId changes
fetchUser(userId);
}, [userId]);
useEffect(() => {
const sub = websocket.subscribe(onMessage);
return () => sub.unsubscribe(); // cleanup on unmount
}, []);useRef
Persists a value without triggering re-render. Also used to reference DOM elements.
const inputRef = useRef(null);
<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>Focus</button>
// Store previous value without re-render
const prevPrice = useRef(price);
useEffect(() => { prevPrice.current = price; }, [price]);useMemo
Memoizes an expensive computed value.
const filteredTrades = useMemo(() =>
trades.filter(t => t.status === activeFilter),
[trades, activeFilter] // only recomputes when these change
);useCallback
Memoizes a function reference so it doesn't change on every render.
const handleSubmit = useCallback((order) => {
dispatch(submitOrder(order));
}, [dispatch]);
// Safe to pass to child without causing re-render
<OrderForm onSubmit={handleSubmit} />useContext
Reads from a React context — avoids prop drilling.
const { user, logout } = useContext(AuthContext);
<button onClick={logout}>{user.name}</button>useReducer
Manages complex state with multiple update paths. Redux-lite.
const [state, dispatch] = useReducer((state, action) => {
switch (action.type) {
case 'FILL': return { ...state, status: 'filled', fillPrice: action.price };
case 'CANCEL': return { ...state, status: 'cancelled' };
default: return state;
}
}, { status: 'pending', fillPrice: null });
dispatch({ type: 'FILL', price: 102.50 });useLayoutEffect
Same as useEffect but fires synchronously after DOM mutations. Use for measuring elements.
useLayoutEffect(() => {
const height = ref.current.getBoundingClientRect().height;
setDropdownHeight(height);
}, [isOpen]);Custom Hook
Extracts reusable stateful logic out of a component.
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(r => r.json())
.then(d => { setData(d); setLoading(false); });
}, [url]);
return { data, loading };
}
// Usage
const { data: trades, loading } = useFetch('/api/trades');
Quick Reference
Hook | Use When |
|---|---|
useState | Simple local state |
useEffect | Fetch, subscriptions, timers |
useRef | DOM access, persist value without re-render |
useMemo | Expensive computation, derived state |
useCallback | Stable function ref passed to child |
useContext | Shared global state without prop drilling |
useReducer | Multiple related state updates, complex logic |
useLayoutEffect | DOM measurements before paint |