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 */}
  </>
);
HTMLTSX
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 componentuseState in that component
a parent and its childrenthe parent, passed down as props
many parts of the appa context (with useReducer if updates are complex)
the serverfetch 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

MistakeWhat you seeFix
Calling a handler: onClick={save()}It runs on every renderPass it: onClick={save} or onClick={() => save(id)}
Changing state directly: books.push(b)The screen does not updateMake a new array: setBooks([...books, b])
No key in a listA console warning, wrong rows updateUse key={item.id}
Hooks inside if or loopsError: rendered fewer hooks than expectedCall hooks at the top of the component
useEffect without a dependency listThe effect runs after every renderAdd [] or the values it uses
Not checking response.okError pages treated as dataThrow when !response.ok
Trusting React to protect dataAnyone can call the APICheck 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/catch and response.ok, protect routes but check on the server too, and optimize only what is slow.