React cheat sheet
A scannable React reference: 13 short snippets across 6 topics, each linking back to the lesson it came from.
At a glance
| Topic | What it covers | |
|---|---|---|
| Components and props | The key is React's identity tag for an element between renders. It must be stable and unique among siblings — a | lesson |
| State with hooks | useState and useReducer, batched updates, immutable updates for objects and arrays, and deriving values instead of | lesson |
| Effects and data fetching | useEffect dependencies and cleanup, why fetching in an effect has sharp edges, and what production code does instead | lesson |
| Setting up a React project with Vite | Scaffold with create-vite, understand the folder layout, how Fast Refresh and the automatic JSX transform work, and the | lesson |
| Testing React components | A test written through roles and labels fails when the component becomes inaccessible, which is exactly the feedback | lesson |
| Production builds, environment config and deployment | What Vite emits, route-level code splitting, why VITE_ variables are public, SPA rewrites on static hosts, bundle | lesson |
Quick snippets
Components and props
Props are read-only
function Price({ amount, currency = 'USD', onSelect }) {
return (
<button onClick={() => onSelect(amount)}>
{currency} {amount.toFixed(2)}
</button>
)
}
// pass a value, a function, or an element
<Price amount={19.5} currency="EUR" onSelect={addToCart} />
<Card header={<Title>Invoice</Title>} />
Lists and keys
function GuideList({ guides }) {
return (
<ul>
{guides.map(guide => (
<li key={guide.id}>
<a href={'/guides/' + guide.slug}>{guide.title}</a>
</li>
))}
</ul>
)
}Full lesson: Components and props →
State with hooks
useState and the rules of updates
// immutable updates: build a new object / array, never mutate the old one
const [form, setForm] = useState({ email: '', name: '' })
setForm(prev => ({ ...prev, email: '[email protected]' })) // object merge
const [tags, setTags] = useState([])
setTags(prev => [...prev, 'new']) // append
setTags(prev => prev.filter(t => t !== 'new')) // remove
setTags(prev => prev.map(t => (t === 'x' ? 'y' : t))) // replaceFull lesson: State with hooks →
Effects and data fetching
Effects and their dependencies
import { useState, useEffect } from 'react'
function Clock() {
const [now, setNow] = useState(() => new Date())
useEffect(() => {
const id = setInterval(() => setNow(new Date()), 1000)
return () => clearInterval(id) // cleanup runs on unmount and before re-running
}, []) // empty array: set up once
return <time>{now.toLocaleTimeString()}</time>
}
Effects and their dependencies
useEffect(() => {
const controller = new AbortController()
fetch(url, { signal: controller.signal })
.then(r => r.json())
.then(setData)
.catch(e => { if (e.name !== 'AbortError') setError(e) })
return () => controller.abort()
}, [url])
What production code does instead
// a query library owns cache, retries, deduplication and refetching
const { data, isPending, error } = useQuery({
queryKey: ['guide', slug],
queryFn: ({ signal }) => fetchGuide(slug, signal),
staleTime: 60_000
})
// mutations declare what becomes stale afterwards
const publish = useMutation({
mutationFn: (id) => fetch('/api/publish/' + id, { method: 'POST' }),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['guides'] })
})Full lesson: Effects and data fetching →
Setting up a React project with Vite
Scaffold and layout
// src/main.tsx - the single entry point of the application
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>
)
TypeScript, lint and formatting
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: { port: 5173, open: true },
build: { sourcemap: true },
resolve: { alias: { '@': new URL('./src', import.meta.url).pathname } }
})Full lesson: Setting up a React project with Vite →
Testing React components
Accessibility and a smoke test
// assert the accessibility contract, not just the DOM structure
expect(screen.getByRole('dialog')).toHaveAttribute('aria-modal', 'true')
expect(screen.getByRole('button', { name: 'Close' })).toBeEnabled()
expect(screen.getByLabelText('Email')).toHaveFocus()
// run an accessibility audit over the rendered tree
import { axe } from 'vitest-axe'
test('the signup form has no accessibility violations', async () => {
const { container } = render(<SignupForm />)
expect(await axe(container)).toHaveNoViolations()
})
Accessibility and a smoke test
// a Playwright smoke test covers the built application end to end
import { expect, test } from '@playwright/test'
test('the home page loads and links to the guides', async ({ page }) => {
await page.goto('http://localhost:4173') // the preview server output
await expect(page.getByRole('heading', { name: /guides/i })).toBeVisible()
await page.getByRole('link', { name: /guides/i }).click()
await expect(page).toHaveURL(/guides/)
})Full lesson: Testing React components →
Production builds, environment config and deployment
Build output and code splitting
import { lazy } from 'react'
// route-level splitting is the highest-value split: the chunk is fetched on first visit
const Settings = lazy(() => import('./routes/Settings'))
// keep heavy, rarely used pieces out of the entry chunk too
const Chart = lazy(() => import('./components/Chart'))
// Vite creates a chunk per dynamic import, named from the module path,
// so a large feature becomes a download the user pays for only if they use it
Environment variables that behave
// src/config.js - read once, validate once, fail loudly
const apiUrl = import.meta.env.VITE_API_URL
if (!apiUrl) {
throw new Error('VITE_API_URL is required')
}
export const API_URL = apiUrl
export const isProduction = import.meta.env.PROD
Rewrites, analysis and monitoring
# inspect what is actually inside each chunk before shipping
npx vite-bundle-visualizer
# a build with the production environment, so the analysis matches production
npm run build -- --mode productionFull lesson: Production builds, environment config and deployment →
FAQ
Is this React cheat sheet free to use?
Where do the examples come from?
How do I go deeper than a cheat sheet?
Related cheat sheets
HTML CSS JavaScript TypeScript HTML DOM AJAX
Last refreshed 2026-09-27.