React Cheat Sheet
By Syncfusion®, Inc. · Last updated
A quick reference for the whole course: TSX, components, props and state, events, forms, hooks, context, state management, routing, authentication, API integration and performance.
How to Use This Cheat Sheet
This page is a quick reference for everything in the course. Each section shows the most common patterns as short, ready-to-copy code.
Use it when you know what you want to do but forget the exact code. Each section names the lesson where the topic is explained in full.
Real-World Example
A developer is building a bookshop page and needs the exact syntax for a controlled input or a useEffect cleanup. Instead of reading a full lesson again, they look it up here in a few seconds and copy the pattern.
TSX
TSX is HTML-like syntax inside TypeScript (Lesson 2).
const name = "Book Corner";
const element = (
<> {/* Fragment: no extra tag */}
<h1 className="title">{name}</h1> {/* {} runs JavaScript */}
<img src="logo.png" alt="Logo" /> {/* close every tag */}
<p style={{ color: "green" }}>Open</p> {/* style is an object */}
</>
);
| HTML | TSX |
|---|---|
class="x" | className="x" |
for="email" | htmlFor="email" |
onclick="..." | onClick={handleClick} |
<br> | <br /> |
Components
A component is a function that returns TSX. Its name starts with a capital letter (Lesson 3).
// BookCard.tsx
export default function BookCard() {
return <div className="card">The Alchemist</div>;
}
// App.tsx
import BookCard from "./BookCard";
export default function App() {
return (
<main>
<BookCard />
<BookCard />
</main>
);
}
Props & State
Props are inputs from the parent (read-only). State is data a component owns and can change (Lessons 4–5).
interface BookProps {
title: string;
price?: number; // ? = optional
children?: ReactNode; // content between the tags
}
function Book({ title, price = 0 }: BookProps) { // default value
return <p>{title}: ₹{price}</p>;
}
const [count, setCount] = useState(0); // number
const [books, setBooks] = useState<string[]>([]); // typed array
const [user, setUser] = useState<User | null>(null); // maybe empty
setCount(count + 1); // new value
setCount((c) => c + 1); // from the previous value
setBooks([...books, "Ikigai"]); // add (new array)
setBooks(books.filter((b) => b !== "Ikigai")); // remove
setUser({ ...user!, name: "Asha" }); // update one field
Data moves down as props, events move up as callbacks, and context reaches any depth
Parent owns the state
Child shows props
Deep child useContext
props
onChange()
context
Props down, events up, context across.
Event Handling Patterns
Pass a function, do not call it (Lesson 6).
<button onClick={handleClick}>Save</button> // pass the function
<button onClick={() => remove(book.id)}>Delete</button> // with an argument
function handleChange(e: ChangeEvent<HTMLInputElement>) {
setName(e.target.value);
}
function handleKey(e: KeyboardEvent<HTMLInputElement>) {
if (e.key === "Enter") search();
}
function handleSubmit(e: FormEvent) {
e.preventDefault(); // stop the page reload
}
<div onClick={() => open()}>
<button onClick={(e) => { e.stopPropagation(); like(); }}>Like</button>
</div>
Conditional rendering and lists (Lessons 7–8):
{isLoading && <p>Loading...</p>}
{error ? <p className="error">{error}</p> : <BookList />}
{books.map((b) => <li key={b.id}>{b.title}</li>)} // key = stable id
Forms & Validation Templates
A controlled form keeps every value in state (Lessons 9–10).
interface FormValues { email: string; password: string; }
type FormErrors = Partial<Record<keyof FormValues, string>>;
function validate(v: FormValues): FormErrors {
const errors: FormErrors = {};
if (!v.email.includes("@")) errors.email = "Enter a valid email.";
if (v.password.length < 8) errors.password = "Use at least 8 characters.";
return errors;
}
const [values, setValues] = useState<FormValues>({ email: "", password: "" });
const [errors, setErrors] = useState<FormErrors>({});
function handleChange(e: ChangeEvent<HTMLInputElement>) {
setValues({ ...values, [e.target.name]: e.target.value }); // one handler
}
function handleSubmit(e: FormEvent) {
e.preventDefault();
const found = validate(values);
setErrors(found);
if (Object.keys(found).length === 0) save(values);
}
React Hooks
Hooks are called at the top of a component, never inside if or loops (Lessons 11–13).
const [value, setValue] = useState(0);
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
const id = setInterval(tick, 1000); // runs after render
return () => clearInterval(id); // cleanup
}, []); // [] = once; [x] = when x changes
const inputRef = useRef<HTMLInputElement>(null);
inputRef.current?.focus();
const total = useMemo(() => sum(items), [items]);
const handleSave = useCallback(() => save(id), [id]);
const theme = useContext(ThemeContext);
// a custom hook: a function starting with "use" that calls hooks
function useToggle(start = false) {
const [on, setOn] = useState(start);
return [on, () => setOn(!on)] as const;
}
Which hook should I use? A quick guide
A value that changes the screen?
useState
Many related updates?
useReducer
Run code after render / fetch?
useEffect
Keep a value without re-render?
useRef
Share data with many parts?
useContext
Start with useState. Reach for the others when you need what they do.
Two rules of hooks: call them only at the top level of a component (not in if, loops or nested functions), and only from components or custom hooks whose names start with use.
Context API
Context shares a value with every component inside its provider (Lesson 15).
interface ThemeValue { theme: "light" | "dark"; toggle: () => void; }
const ThemeContext = createContext<ThemeValue | null>(null);
export function ThemeProvider({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState<"light" | "dark">("light");
const toggle = () => setTheme(theme === "light" ? "dark" : "light");
return <ThemeContext.Provider value={{ theme, toggle }}>{children}</ThemeContext.Provider>;
}
export function useTheme() {
const ctx = useContext(ThemeContext);
if (!ctx) throw new Error("useTheme must be used inside ThemeProvider");
return ctx;
}
// anywhere inside the provider
const { theme, toggle } = useTheme();
State Management
Where should state live? (Lesson 14)
| The data is used by... | Put the state in... |
|---|---|
| one component | useState in that component |
| a parent and its children | the parent, passed down as props |
| many parts of the app | a context (with useReducer if updates are complex) |
| the server | fetch it, and keep a copy in state |
type Action =
| { type: "added"; item: Item }
| { type: "removed"; id: number };
function cartReducer(items: Item[], action: Action): Item[] {
switch (action.type) {
case "added": return [...items, action.item];
case "removed": return items.filter((i) => i.id !== action.id);
}
}
const [items, dispatch] = useReducer(cartReducer, []);
dispatch({ type: "added", item: book });
Routing
React Router shows a page for each URL (Lesson 16).
import { BrowserRouter, Routes, Route, Link, NavLink, useParams, useNavigate } from "react-router-dom";
<BrowserRouter>
<nav>
<NavLink to="/" end>Home</NavLink> {/* gets class "active" */}
<Link to="/books">Books</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/books" element={<BookList />} />
<Route path="/books/:id" element={<BookDetail />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
const { id } = useParams(); // "/books/2" -> id is "2" (text)
const navigate = useNavigate();
navigate("/books"); // go to a page in code
navigate(-1); // go back
Authentication & Authorization
Authentication checks who you are. Authorization checks what you may do (Lesson 17).
// after login, keep the JWT and the user in an auth context
const { token, user } = useAuth();
// send the token with each request
fetch(API + "/orders", { headers: { Authorization: "Bearer " + token } });
// read the payload (the middle part) of a JWT, for display only
const payload = JSON.parse(atob(token.split(".")[1]));
// protect a route
function ProtectedRoute({ children, role }: { children: ReactNode; role?: string }) {
const { user } = useAuth();
if (!user) return <Navigate to="/login" replace />;
if (role && user.role !== role) return <p>You do not have access.</p>;
return <>{children}</>;
}
<Route path="/admin" element={<ProtectedRoute role="admin"><Admin /></ProtectedRoute>} />
Hiding a page in React is only for the user's comfort. The server must still check the token on every request, because anyone can change code in their browser.
API Integration
Fetch data with loading and error states (Lesson 22).
const [books, setBooks] = useState<Book[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
useEffect(() => {
async function load() {
try {
const response = await fetch(import.meta.env.VITE_API_URL + "/books");
if (!response.ok) throw new Error("Status " + response.status);
setBooks(await response.json());
} catch {
setError("Could not load books. Please try again.");
} finally {
setLoading(false);
}
}
load();
}, []);
// POST, PUT and DELETE
await fetch(url, {
method: "POST", // or "PUT"
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newBook),
});
await fetch(url + "/" + id, { method: "DELETE" });
Error boundaries for render crashes (Lesson 24): a class component with static getDerivedStateFromError() that renders a fallback.
Performance Optimization
Measure first, then optimize the slow parts (Lesson 25).
const BookRow = memo(function BookRow({ book }: { book: Book }) { ... }); // skip same props
const cheap = useMemo(() => books.filter((b) => b.price < 300), [books]); // keep a value
const handleSelect = useCallback((id: number) => select(id), []); // keep a function
const Admin = lazy(() => import("./Admin")); // code splitting
<Suspense fallback={<p>Loading...</p>}>
<Admin />
</Suspense>
- Keep state close to where it is used.
- Use stable keys (ids, not indexes) in lists.
- Test speed with a production build (
npm run build).
Easy Way to Remember: state for change, props for passing, effects for outside work, context for sharing, memo for speed.
Common mistakes
| Mistake | What you see | Fix |
|---|---|---|
Calling a handler: onClick={save()} | It runs on every render | Pass it: onClick={save} or onClick={() => save(id)} |
Changing state directly: books.push(b) | The screen does not update | Make a new array: setBooks([...books, b]) |
No key in a list | A console warning, wrong rows update | Use key={item.id} |
Hooks inside if or loops | Error: rendered fewer hooks than expected | Call hooks at the top of the component |
useEffect without a dependency list | The effect runs after every render | Add [] or the values it uses |
Not checking response.ok | Error pages treated as data | Throw when !response.ok |
| Trusting React to protect data | Anyone can call the API | Check tokens on the server too |
Check Yourself
What to Remember
- Keep this page open while you build. Each section points to the lesson with the full explanation.
- Props down, events up, context across. State changes go through setters, with new arrays and objects.
- Fetch with
try/catchandresponse.ok, protect routes but check on the server too, and optimize only what is slow.