React Cheat Sheet
React hooks, components, state, effects, context, refs, and common patterns — everything you reach for daily in one quick-reference page.
8 sections 24 snippets
Components
Function component
function Greeting({ name }: { name: string }) {
return <h1>Hello, {name}!</h1>;
} Props with children
function Card({ title, children }: {
title: string;
children: React.ReactNode;
}) {
return (
<div className="card">
<h2>{title}</h2>
{children}
</div>
);
} Conditional rendering
{isLoggedIn ? <Dashboard /> : <Login />}
{error && <ErrorBanner message={error} />}
{items.length > 0 && <List items={items} />} List rendering
{users.map(user => (
<UserCard key={user.id} user={user} />
))} useState
Basic state
const [count, setCount] = useState(0);
setCount(count + 1);
setCount(prev => prev + 1); // functional update Object state
const [form, setForm] = useState({ name: '', email: '' });
setForm(prev => ({ ...prev, name: 'Alice' })); Lazy initialization
const [data, setData] = useState(() => {
return JSON.parse(localStorage.getItem('data') ?? '[]');
}); useEffect
Run on mount
useEffect(() => {
fetchData();
}, []); // empty deps = mount only Run on dependency change
useEffect(() => {
fetchUser(userId);
}, [userId]); Cleanup
useEffect(() => {
const timer = setInterval(tick, 1000);
return () => clearInterval(timer);
}, []); Abort fetch on unmount
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(r => r.json())
.then(setData);
return () => controller.abort();
}, [url]); useRef and useCallback
DOM ref
const inputRef = useRef<HTMLInputElement>(null);
// ...
<input ref={inputRef} />
// ...
inputRef.current?.focus(); Mutable ref (no re-render)
const renderCount = useRef(0);
useEffect(() => { renderCount.current += 1; }); useCallback
const handleClick = useCallback((id: number) => {
setSelected(id);
}, []); Stabilizes function identity to prevent child re-renders
useMemo and React.memo
useMemo
const sorted = useMemo(
() => items.toSorted((a, b) => a.name.localeCompare(b.name)),
[items]
); React.memo
const ExpensiveList = React.memo(function ExpensiveList({
items
}: { items: Item[] }) {
return <ul>{items.map(renderItem)}</ul>;
}); Context
Create and provide
const ThemeCtx = createContext<'light' | 'dark'>('light');
function App() {
return (
<ThemeCtx.Provider value="dark">
<Page />
</ThemeCtx.Provider>
);
} Consume
function Page() {
const theme = useContext(ThemeCtx);
return <div className={theme}>...</div>;
} Custom hook pattern
function useTheme() {
const ctx = useContext(ThemeCtx);
if (!ctx) throw new Error('useTheme must be inside ThemeProvider');
return ctx;
} Forms
Controlled input
const [email, setEmail] = useState('');
<input
value={email}
onChange={e => setEmail(e.target.value)}
/> Form submit
function handleSubmit(e: React.FormEvent) {
e.preventDefault();
const formData = new FormData(e.currentTarget as HTMLFormElement);
const name = formData.get('name') as string;
} Common Patterns
Custom hook
function useLocalStorage<T>(key: string, init: T) {
const [val, setVal] = useState<T>(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : init;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(val));
}, [key, val]);
return [val, setVal] as const;
} Error boundary
class ErrorBoundary extends React.Component<
{ children: React.ReactNode; fallback: React.ReactNode },
{ hasError: boolean }
> {
state = { hasError: false };
static getDerivedStateFromError() { return { hasError: true }; }
render() {
if (this.state.hasError) return this.props.fallback;
return this.props.children;
}
} Portal
import { createPortal } from 'react-dom';
function Modal({ children }: { children: React.ReactNode }) {
return createPortal(children, document.getElementById('modal-root')!);
}