React Cheat Sheet
Use this React cheat sheet as a quick reference for components, JSX, props, state, events, lists, forms, effects, refs, context, hooks, routing patterns, and common mistakes.
Basic React Component
A React component is a JavaScript function that returns UI.
Learn React on Mimo
JSX
function Welcome() {
return <h1>Hello, React</h1>;
}
export default Welcome;
Use the component inside another component:
JSX
function App() {
return (
<main>
<Welcome />
</main>
);
}
Component Basics
- Component names must start with a capital letter.
- Components return JSX.
- JSX looks like HTML but follows JavaScript rules.
- Components can receive data through props.
- Components can manage local data with state.
JSX Basics
JSX lets you write UI inside JavaScript.
JSX
function App() {
return (
<section>
<h1>My App</h1>
<p>Welcome to the page.</p>
</section>
);
}
JSX Rules
- Return one parent element.
- Use
classNameinstead ofclass. - Use
htmlForinstead offor. - Close every tag.
- Wrap JavaScript expressions in curly braces.
- Use
camelCasefor most DOM attributes.
Return One Parent Element
React components must return one parent element.
JSX
function Profile() {
return (
<div>
<h1>Alex</h1>
<p>Frontend Developer</p>
</div>
);
}
You can also use a fragment when you do not want an extra element.
JSX
function Profile() {
return (
<>
<h1>Alex</h1>
<p>Frontend Developer</p>
</>
);
}
JavaScript in JSX
Use curly braces to add JavaScript expressions inside JSX.
JSX
function UserGreeting() {
const name = "Alex";
return <h1>Hello, {name}</h1>;
}
Use expressions, not statements.
JSX
function Price() {
const price = 20;
const quantity = 3;
return <p>Total: {price * quantity}</p>;
}
This works because price * quantity returns a value.
Attributes in JSX
Class Name
JSX
function Button() {
return <button className="primary-button">Click me</button>;
}
Inline Styles
JSX
function Card() {
return (
<article style={{ padding: "24px", borderRadius: "12px" }}>
Card content
</article>
);
}
Inline styles use an object. CSS property names use camelCase.
Labels
JSX
function EmailField() {
return (
<label htmlFor="email">
Email
<input id="email" type="email" />
</label>
);
}
Use htmlFor because for is a reserved word in JavaScript.
Props
Props pass data from a parent component to a child component.
JSX
function UserCard(props) {
return <h2>{props.name}</h2>;
}
function App() {
return <UserCard name="Alex" />;
}
Destructure Props
JSX
function UserCard({ name, role }) {
return (
<article>
<h2>{name}</h2>
<p>{role}</p>
</article>
);
}
Default Prop Value
JSX
function Avatar({ name = "Guest" }) {
return <p>{name}</p>;
}
Pass Numbers and Booleans
JSX
function Product({ title, price, inStock }) {
return (
<article>
<h2>{title}</h2>
<p>${price}</p>
<p>{inStock ? "In stock" : "Out of stock"}</p>
</article>
);
}
function App() {
return <Product title="Course" price={29} inStock={true} />;
}
Use curly braces for non-string values.
Children
Use children when a component should wrap other content.
JSX
function Card({ children }) {
return <article className="card">{children}</article>;
}
function App() {
return (
<Card>
<h2>React Basics</h2>
<p>Learn components, props, and state.</p>
</Card>
);
}
children helps you create reusable layout components.
State with useState
Use state for values that change and should update the UI.
JSX
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
State Basics
countis the current value.setCountupdates the value.useState(0)sets the initial value.- Updating state re-renders the component.
Update State Based on Previous State
Use the callback form when the next state depends on the previous state.
JSX
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
function increase() {
setCount((previousCount) => previousCount + 1);
}
return <button onClick={increase}>Count: {count}</button>;
}
This is safer when state updates may happen close together.
State with Objects
JSX
import { useState } from "react";
function ProfileForm() {
const [user, setUser] = useState({
name: "Alex",
email: "alex@example.com"
});
function updateName() {
setUser({
...user,
name: "Sam"
});
}
return (
<>
<p>{user.name}</p>
<button onClick={updateName}>Change name</button>
</>
);
}
Do not mutate state directly. Create a new object with the changed value.
State with Arrays
JSX
import { useState } from "react";
function TodoList() {
const [todos, setTodos] = useState(["Learn React"]);
function addTodo() {
setTodos([...todos, "Build a project"]);
}
return (
<ul>
{todos.map((todo) => (
<li key={todo}>{todo}</li>
))}
</ul>
);
}
Use methods like map, filter, and spread syntax to create new arrays.
Events
React events use camelCase names.
JSX
function Button() {
function handleClick() {
console.log("Clicked");
}
return <button onClick={handleClick}>Click me</button>;
}
Inline Event Handler
JSX
function Button() {
return (
<button onClick={() => console.log("Clicked")}>
Click me
</button>
);
}
Event Object
JSX
function SearchInput() {
function handleChange(event) {
console.log(event.target.value);
}
return <input type="text" onChange={handleChange} />;
}
Common event props include:
onClickonChangeonSubmitonFocusonBluronKeyDown
Conditional Rendering
Use if
JSX
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>Welcome back</h1>;
}
return <h1>Please log in</h1>;
}
Use a Ternary
JSX
function Greeting({ isLoggedIn }) {
return (
<h1>{isLoggedIn ? "Welcome back" : "Please log in"}</h1>
);
}
Use &&
JSX
function Alert({ message }) {
return (
<div>
{message && <p className="alert">{message}</p>}
</div>
);
}
Use && when you only want to show something if a value exists.
Render Lists
Use map() to render lists.
JSX
function CourseList() {
const courses = ["HTML", "CSS", "React"];
return (
<ul>
{courses.map((course) => (
<li key={course}>{course}</li>
))}
</ul>
);
}
List of Objects
JSX
function ProductList() {
const products = [
{ id: 1, name: "HTML Course" },
{ id: 2, name: "CSS Course" },
{ id: 3, name: "React Course" }
];
return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}
Key Rules
- Add a
keyprop to each rendered item. - Use stable IDs when possible.
- Avoid array indexes as keys when items can be reordered, added, or removed.
Forms
Controlled Input
JSX
import { useState } from "react";
function NameForm() {
const [name, setName] = useState("");
return (
<input
value={name}
onChange={(event) => setName(event.target.value)}
placeholder="Your name"
/>
);
}
A controlled input stores its value in React state.
Submit a Form
JSX
import { useState } from "react";
function SignupForm() {
const [email, setEmail] = useState("");
function handleSubmit(event) {
event.preventDefault();
console.log(email);
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
/>
<button type="submit">Sign up</button>
</form>
);
}
Use event.preventDefault() when you want React to handle the form instead of the browser reloading the page.
useEffect
Use useEffect to run code after rendering.
JSX
import { useEffect } from "react";
function PageTitle() {
useEffect(() => {
document.title = "React App";
}, []);
return <h1>Home</h1>;
}
Effect with a Dependency
JSX
import { useEffect } from "react";
function SearchResults({ query }) {
useEffect(() => {
console.log(`Search changed: ${query}`);
}, [query]);
return <p>Results for {query}</p>;
}
The effect runs when query changes.
Cleanup Function
JSX
import { useEffect } from "react";
function Timer() {
useEffect(() => {
const intervalId = setInterval(() => {
console.log("Tick");
}, 1000);
return () => {
clearInterval(intervalId);
};
}, []);
return <p>Timer running</p>;
}
Use cleanup for timers, subscriptions, and event listeners.
Fetch Data with useEffect
JSX
import { useEffect, useState } from "react";
function Users() {
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
async function loadUsers() {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await response.json();
setUsers(data);
setIsLoading(false);
}
loadUsers();
}, []);
if (isLoading) {
return <p>Loading...</p>;
}
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
For larger apps, use a framework or data-fetching library when you need caching, loading states, and server rendering.
useRef
Use useRef to store a value that does not trigger a re-render, or to access a DOM element.
Focus an Input
JSX
import { useRef } from "react";
function SearchBox() {
const inputRef = useRef(null);
function focusInput() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus</button>
</>
);
}
Store a Mutable Value
JSX
import { useRef } from "react";
function ClickTracker() {
const clickCount = useRef(0);
function handleClick() {
clickCount.current += 1;
console.log(clickCount.current);
}
return <button onClick={handleClick}>Track clicks</button>;
}
Changing a ref does not re-render the component.
useMemo
Use useMemo to avoid recalculating an expensive value unless its dependencies change.
JSX
import { useMemo } from "react";
function ProductList({ products, search }) {
const filteredProducts = useMemo(() => {
return products.filter((product) =>
product.name.toLowerCase().includes(search.toLowerCase())
);
}, [products, search]);
return (
<ul>
{filteredProducts.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}
Use useMemo when a calculation is actually expensive or causes avoidable work.
useCallback
Use useCallback to keep a function reference stable between renders.
JSX
import { useCallback, useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
const increase = useCallback(() => {
setCount((previousCount) => previousCount + 1);
}, []);
return <button onClick={increase}>Count: {count}</button>;
}
Use this mainly when passing callbacks to memoized child components.
React.memo
Use memo to skip re-rendering a component when its props have not changed.
JSX
import { memo } from "react";
const UserCard = memo(function UserCard({ name }) {
return <p>{name}</p>;
});
export default UserCard;
Use it for components that render often with the same props. Avoid adding it everywhere by default.
Context
Context passes data through the component tree without manually passing props at every level.
JSX
import { createContext, useContext } from "react";
const ThemeContext = createContext("light");
function ThemeLabel() {
const theme = useContext(ThemeContext);
return <p>Current theme: {theme}</p>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemeLabel />
</ThemeContext.Provider>
);
}
Use context for shared values such as theme, current user, locale, or feature settings.
Custom Hooks
A custom hook is a reusable function that uses React hooks.
JSX
import { useEffect, useState } from "react";
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return width;
}
function LayoutInfo() {
const width = useWindowWidth();
return <p>Window width: {width}</p>;
}
Custom hook names must start with use.
Rules of Hooks
Follow these rules when using hooks:
- Call hooks only at the top level of a component or custom hook.
- Do not call hooks inside loops, conditions, or nested functions.
- Call hooks only from React functions.
- Keep dependency arrays accurate.
- Use custom hooks to reuse hook logic.
Wrong:
JSX
function Profile({ isLoggedIn }) {
if (isLoggedIn) {
const [name, setName] = useState("Alex");
}
return <p>Profile</p>;
}
Better:
JSX
function Profile({ isLoggedIn }) {
const [name, setName] = useState("Alex");
if (!isLoggedIn) {
return <p>Please log in</p>;
}
return <p>{name}</p>;
}
Styling in React
CSS Class
JSX
function Button() {
return <button className="button">Click me</button>;
}
CSS
.button {
padding: 12px 20px;
border-radius: 8px;
}
Conditional Class
JSX
function Button({ isActive }) {
return (
<button className={isActive ? "button active" : "button"}>
Save
</button>
);
}
Inline Style
JSX
function Alert() {
return (
<p style={{ color: "red", fontWeight: "bold" }}>
Something went wrong
</p>
);
}
Use CSS classes for most styling. Use inline styles for dynamic values or small one-off styles.
React Router Pattern
React itself does not include routing. Many apps use a router library.
JSX
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
Use your framework’s routing system if you work with Next.js, Remix, or another React framework.
Code Splitting with lazy
Use lazy to load a component only when needed.
JSX
import { lazy, Suspense } from "react";
const SettingsPage = lazy(() => import("./SettingsPage"));
function App() {
return (
<Suspense fallback={<p>Loading...</p>}>
<SettingsPage />
</Suspense>
);
}
This can reduce the initial JavaScript loaded by the page.
Error Boundaries
Error boundaries catch rendering errors in child components.
JSX
import { Component } from "react";
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false
};
}
static getDerivedStateFromError() {
return {
hasError: true
};
}
render() {
if (this.state.hasError) {
return <p>Something went wrong.</p>;
}
return this.props.children;
}
}
Use it like this:
JSX
function App() {
return (
<ErrorBoundary>
<Dashboard />
</ErrorBoundary>
);
}
Error boundaries do not catch every type of error, but they help prevent a full UI crash from render errors.
Server Components
Some React frameworks support Server Components.
JSX
export default async function ProductsPage() {
const response = await fetch("https://example.com/api/products");
const products = await response.json();
return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}
Use Server Components for data fetching and read-only UI. Use Client Components for state, effects, event handlers, and browser APIs.
In Next.js App Router, add "use client" at the top when a component needs client-side behavior.
JSX
"use client";
import { useState } from "react";
function LikeButton() {
const [likes, setLikes] = useState(0);
return (
<button onClick={() => setLikes(likes + 1)}>
Likes: {likes}
</button>
);
}
Common React Patterns
Toggle UI
JSX
import { useState } from "react";
function TogglePanel() {
const [isOpen, setIsOpen] = useState(false);
return (
<section>
<button onClick={() => setIsOpen(!isOpen)}>
Toggle
</button>
{isOpen && <p>Panel content</p>}
</section>
);
}
Filter a List
JSX
import { useState } from "react";
function CourseSearch() {
const [search, setSearch] = useState("");
const courses = ["HTML", "CSS", "JavaScript", "React"];
const filteredCourses = courses.filter((course) =>
course.toLowerCase().includes(search.toLowerCase())
);
return (
<>
<input
value={search}
onChange={(event) => setSearch(event.target.value)}
placeholder="Search courses"
/>
<ul>
{filteredCourses.map((course) => (
<li key={course}>{course}</li>
))}
</ul>
</>
);
}
Add an Item
JSX
import { useState } from "react";
function TodoApp() {
const [todos, setTodos] = useState([]);
const [text, setText] = useState("");
function addTodo(event) {
event.preventDefault();
if (!text.trim()) {
return;
}
setTodos([...todos, text]);
setText("");
}
return (
<form onSubmit={addTodo}>
<input
value={text}
onChange={(event) => setText(event.target.value)}
/>
<button type="submit">Add</button>
<ul>
{todos.map((todo) => (
<li key={todo}>{todo}</li>
))}
</ul>
</form>
);
}
Remove an Item
JSX
import { useState } from "react";
function TodoList() {
const [todos, setTodos] = useState([
{ id: 1, text: "Learn React" },
{ id: 2, text: "Build a project" }
]);
function removeTodo(id) {
setTodos(todos.filter((todo) => todo.id !== id));
}
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>
{todo.text}
<button onClick={() => removeTodo(todo.id)}>
Remove
</button>
</li>
))}
</ul>
);
}
Common Mistakes
Mutating State Directly
JSX
const [user, setUser] = useState({ name: "Alex" });
user.name = "Sam";
setUser(user);
Better:
JSX
setUser({
...user,
name: "Sam"
});
Create a new object or array when updating state.
Missing Keys in Lists
JSX
{courses.map((course) => (
<li>{course}</li>
))}
Better:
JSX
{courses.map((course) => (
<li key={course}>{course}</li>
))}
Keys help React track list items.
Calling a Function Instead of Passing It
JSX
<button onClick={handleClick()}>Click me</button>
Better:
JSX
<button onClick={handleClick}>Click me</button>
Use an arrow function when you need to pass an argument.
JSX
<button onClick={() => handleDelete(id)}>Delete</button>
Using class Instead of className
JSX
<div class="card">Content</div>
Better:
JSX
<div className="card">Content</div>
JSX uses className.
Forgetting to Clean Up Effects
JSX
useEffect(() => {
window.addEventListener("resize", handleResize);
}, []);
Better:
JSX
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
Clean up event listeners, timers, and subscriptions.
Using State for Values That Can Be Derived
JSX
const [fullName, setFullName] = useState(`${firstName} ${lastName}`);
Better:
JSX
const fullName = `${firstName} ${lastName}`;
Store state only when the value needs to change independently.
Debugging Tips
Log Props and State
JSX
function UserCard({ user }) {
console.log(user);
return <h2>{user.name}</h2>;
}
Use React Developer Tools
Use React Developer Tools to inspect:
- Component tree
- Props
- State
- Hooks
- Context values
- Render performance with the Profiler
Check the Browser Console
React errors often tell you:
- Which component failed
- Which prop or value caused the issue
- Which hook rule was broken
- Which list needs a key
Isolate the Component
Move the failing component into a smaller example with hardcoded props.
JSX
function TestPage() {
return <UserCard user={{ name: "Alex" }} />;
}
This helps you find whether the bug comes from the component or the data passed into it.
Quick Reference
Create a Component
JSX
function App() {
return <h1>Hello</h1>;
}
Use Props
JSX
function Greeting({ name }) {
return <p>Hello, {name}</p>;
}
Use State
JSX
const [count, setCount] = useState(0);
Handle Clicks
JSX
<button onClick={handleClick}>Click</button>
Render a List
JSX
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
Render Conditionally
JSX
{isLoggedIn ? <Dashboard /> : <Login />}
Run an Effect
JSX
useEffect(() => {
document.title = "React App";
}, []);
Use a Ref
JSX
const inputRef = useRef(null);
Use Context
JSX
const value = useContext(MyContext);
Create a Custom Hook
JSX
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
function toggle() {
setValue((currentValue) => !currentValue);
}
return [value, toggle];
}
Export a Component
JSX
export default App;
Import a Component
JSX
import App from "./App";
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot