React Cheat Sheet
A one-page reference for React 19 with function components and hooks: JSX, props, state, events, lists, forms, effects and refs. Each section links to the lesson that explains it in full.
Rendering an app Lesson
import { createRoot } from "react-dom/client"; | Loads the function that mounts React into the page |
<div id="root"></div> | Empty element in the HTML that React fills |
createRoot(document.getElementById("root")).render(<App />); | Renders the App component inside #root |
import { useState } from "react"; | Hooks are named imports from the react package |
<StrictMode><App /></StrictMode> | Extra development-only checks; no effect in production |
React updates only the parts of the page whose data changed; you describe the UI, React does the DOM work.
JSX Lesson
<h1>Hello, {name}</h1> | Curly braces insert any JavaScript expression |
<p>Total: ₹{price * qty}</p> | Expressions can calculate values inline |
<div className="card"> | Use className, not class |
<label htmlFor="email"> | Use htmlFor, not for |
<img src={url} alt="Logo" /> | Every tag must be closed, even empty ones |
style={{ color: "teal", fontSize: 18 }} | Styles are an object with camelCase keys |
<>…</> | Fragment: one root without adding an extra element |
{/* comment */} | A comment inside JSX |
return ( <main>…</main> ); | Wrap multi-line JSX in brackets after return |
A component must return a single root element; wrap siblings in a fragment.
Components Lesson
function Card() { return <div>…</div>; } | A component is a function that returns JSX |
<Card /> | Use a component like an HTML tag |
function ProductCard() | Names start with a capital letter |
export default function App() { … } | Shares the component from its file |
import Card from "./Card.jsx"; | Loads a default export from another file |
return null; | Renders nothing |
Same props → same JSX | Keep components pure: no side effects while rendering |
Never define a component inside another component; declare each one at the top level.
Props Lesson
<Greeting name="Priya" age={25} /> | Strings in quotes, everything else in braces |
function Greeting({ name, age }) { … } | Destructure props in the parameter list |
function Button({ size = "md" }) | Default value used when the prop is missing |
<Panel>Some text</Panel> | Content between tags arrives as children |
function Panel({ children }) { … } | Render {children} where the content belongs |
<Item {...product} /> | Spread an object to pass all its keys as props |
<Menu onSelect={handleSelect} /> | Functions can be passed as props too |
props.name = "x"; // ✗ | Props are read-only; never change them |
State with useState Lesson
const [count, setCount] = useState(0); | State value plus a setter; 0 is the initial value |
setCount(count + 1); | Sets a new value and schedules a re-render |
setCount(c => c + 1); | Updater function: uses the latest pending value |
setUser({ ...user, city: "Madurai" }); | Copy objects; never mutate state directly |
setItems([...items, newItem]); | Add to an array by making a new array |
setItems(items.filter(i => i.id !== id)); | Remove from an array without mutating |
useState(() => loadSaved()) | Lazy initial value, calculated only on first render |
Call hooks at the top level | Not inside conditions, loops or nested functions |
State is a snapshot: after setCount(5), count keeps its old value until the next render.
Events Lesson
<button onClick={handleClick}> | Pass the function; do not call it |
onClick={handleClick()} // ✗ | Calls it during render instead of on click |
onClick={() => remove(item.id)} | Arrow function to pass arguments |
function handleChange(e) { e.target.value } | The event object gives the element and its value |
e.preventDefault(); | Stops the browser default, e.g. a form reload |
e.stopPropagation(); | Stops the event reaching parent handlers |
onChange, onSubmit, onKeyDown, onFocus | Event props are camelCase |
<Toolbar onSave={handleSave} /> | Convention: onX props, handleX functions |
Conditional rendering Lesson
if (!user) return <Login />; | Early return for a whole different output |
{isOpen ? <Menu /> : <MenuButton />} | Ternary: show this or that |
{hasError && <p>Try again</p>} | Show something or nothing |
{items.length > 0 && <List />} | Use a real boolean; {0 && …} renders 0 |
let content = <Spinner />; | Store JSX in a variable, then render {content} |
return null; | A component can choose to render nothing |
Not rendering a component removes it and its state; hiding it with CSS keeps both.
Lists and keys Lesson
{items.map(i => <li key={i.id}>{i.name}</li>)} | Turn an array into elements with map() |
items.filter(i => i.inStock).map(…) | Filter first, then render |
items.toSorted((a, b) => a.price - b.price) | Sorted copy; the original array is untouched |
key={item.id} | Keys must be unique among siblings and stable |
key={index} | Only if the list never reorders, inserts or deletes |
<Fragment key={row.id}>…</Fragment> | Keyed fragment; <> cannot take a key |
props.key // undefined | A key is not passed to the component as a prop |
Forms Lesson
<input value={name} onChange={e => setName(e.target.value)} /> | Controlled input: state holds the value |
<input type="checkbox" checked={ok} onChange={…} /> | Checkboxes use checked and e.target.checked |
<select value={city} onChange={…}> | Controlled select; same for <textarea value> |
<input defaultValue="Chennai" /> | Uncontrolled: starts with a value, React doesn't track it |
Number(e.target.value) | Input values are always strings |
<form onSubmit={handleSubmit}> | Call e.preventDefault() inside the handler |
<form action={saveReview}> | React 19: the function receives a FormData object |
formData.get("email") | Reads a field by its name attribute |
const [state, action, isPending] = useActionState(fn, init); | Tracks an action's result and pending state |
const { pending } = useFormStatus(); | From react-dom; call in a child of the form |
Client-side validation is a convenience; the server must always check the data again.
useEffect Lesson
useEffect(() => { … }); | Runs after every render |
useEffect(() => { … }, []); | Runs once after the component first appears |
useEffect(() => { … }, [userId]); | Runs again when userId changes |
return () => clearInterval(id); | Cleanup: runs before the next run and on removal |
let ignore = false; … return () => { ignore = true; }; | Ignore stale fetch results after a change |
Strict Mode: setup → cleanup → setup | Development only, to test your cleanup |
const total = price * qty; | Derived values: calculate while rendering, no effect needed |
Effects are for syncing with things outside React: timers, subscriptions, network requests.
useRef and custom hooks Lesson
const inputRef = useRef(null); | A box that survives re-renders: { current: null } |
<input ref={inputRef} /> | React puts the DOM node in inputRef.current |
inputRef.current.focus(); | Use the DOM node in an event handler or effect |
timerRef.current = setInterval(…); | Changing .current does not re-render |
function Field({ ref, ...rest }) { … } | React 19: ref is a normal prop; no forwardRef |
function useWindowWidth() { … } | Custom hook: name starts with use + capital |
const width = useWindowWidth(); | Each component calling it gets its own state |
Do not read or write ref.current during rendering; if the screen shows it, use state.
A project with Vite Lesson
node -v | Check Node.js is installed (Vite needs a recent LTS) |
npm create vite@latest my-app -- --template react | Creates a new React project |
npm install | Installs the project's packages |
npm run dev | Starts the dev server, usually at localhost:5173 |
npm run build | Writes an optimised build to the dist folder |
npm run preview | Serves the built dist folder locally to test |
src/main.jsx | Entry file that calls createRoot(…).render() |
--template react-ts | Same starter, with TypeScript |
create-react-app is deprecated; start new projects with Vite or a framework.