1import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
2
3// useState — local state with type inference
4function Counter() {
5 const [count, setCount] = useState(0);
6 const [error, setError] = useState<string | null>(null);
7
8 return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
9}
10
11// useEffect — synchronise with external systems
12function UserProfile({ userId }: { userId: string }) {
13 const [user, setUser] = useState<User | null>(null);
14
15 useEffect(() => {
16 let cancelled = false;
17 fetch(`/api/users/${userId}`)
18 .then(r => r.json())
19 .then(data => { if (!cancelled) setUser(data); });
20 return () => { cancelled = true; }; // cleanup
21 }, [userId]); // re-run when userId changes
22
23 return user ? <div>{user.name}</div> : <div>Loading...</div>;
24}
25
26// useCallback — stable function reference for memo children
27function Parent() {
28 const [value, setValue] = useState('');
29 const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
30 setValue(e.target.value);
31 }, []); // never recreated
32
33 return <ExpensiveChild onChange={handleChange} />;
34}
35
36// useMemo — expensive computation cached by deps
37function DataTable({ rows }: { rows: Row[] }) {
38 const sorted = useMemo(
39 () => [...rows].sort((a, b) => b.score - a.score),
40 [rows] // recalculate only when rows changes
41 );
42 return <table>{sorted.map(r => <tr key={r.id}><td>{r.score}</td></tr>)}</table>;
43}
44
45// useRef — mutable value without re-render / DOM access
46function StopWatch() {
47 const intervalRef = useRef<number | null>(null);
48 const [time, setTime] = useState(0);
49
50 const start = () => {
51 intervalRef.current = setInterval(() => setTime(t => t + 1), 1000);
52 };
53 const stop = () => {
54 if (intervalRef.current) clearInterval(intervalRef.current);
55 };
56 return <div>{time}s <button onClick={start}>Start</button><button onClick={stop}>Stop</button></div>;
57}
58
59type User = { name: string };
60type Row = { id: string; score: number };
61declare const ExpensiveChild: any;