React Quick Reference
Everything you need day‑to‑day – components, hooks, state, routing, and best practices.
JSX
// Basic JSX const element = <h1>Hello, world!</h1>; // Embedding expressions const name = "Alice"; const element = <h1>Hello, {name}!</h1>; // Attributes const img = <img src={imageUrl} alt="Description" />; // Class vs className (use className) const div = <div className="container">Content</div>; // Inline styles (camelCase) const div = <div style={{ color: 'red', fontSize: '16px' }}>Content</div>; // Fragments (no extra DOM node) <React.Fragment> <h1>Title</h1> <p>Content</p> </React.Fragment> // Short syntax <> <h1>Title</h1> <p>Content</p> </>
Components
Functional Component
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Arrow function
const Greeting = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
Component with Props
function UserCard({ name, age, email, children }) {
return (
<div className="card">
<h2>{name}</h2>
<p>Age: {age}</p>
<p>Email: {email}</p>
{children}
</div>
);
}
// Usage
<UserCard name="Alice" age={25} email="alice@example.com">
<p>Additional content</p>
</UserCard>
Default Props
function Greeting({ name = "Guest" }) {
return <h1>Hello, {name}!</h1>;
}
// Alternative
Greeting.defaultProps = {
name: "Guest"
};
State Management
useState
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}
// Functional update (when next state depends on previous)
setCount(prev => prev + 1);
// Object state
const [user, setUser] = useState({ name: '', age: 0 });
setUser(prev => ({ ...prev, age: prev.age + 1 }));
Lifting State Up
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<Child count={count} setCount={setCount} />
</div>
);
}
function Child({ count, setCount }) {
return (
<button onClick={() => setCount(count + 1)}>
Increment: {count}
</button>
);
}
Effects (useEffect)
import { useEffect } from 'react';
function Example() {
useEffect(() => {
// Runs after every render (by default)
console.log("Component rendered");
// Cleanup (optional)
return () => {
console.log("Cleanup");
};
});
// Runs only on mount (empty dependency array)
useEffect(() => {
console.log("Mounted");
}, []);
// Runs when count changes
useEffect(() => {
console.log("Count changed:", count);
}, [count]);
// Runs when count OR name changes
useEffect(() => {
console.log("Count or name changed");
}, [count, name]);
return <div>Example</div>;
}
Refs (useRef)
import { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
// Mutable ref (persists between renders)
function Timer() {
const countRef = useRef(0);
const increment = () => {
countRef.current++;
console.log(countRef.current);
};
return <button onClick={increment}>Increment</button>;
}
Memoization
useMemo
import { useMemo, useState } from 'react';
function ExpensiveComponent({ numbers }) {
const [filter, setFilter] = useState('');
// Only recompute when numbers changes
const total = useMemo(() => {
console.log("Calculating total...");
return numbers.reduce((sum, n) => sum + n, 0);
}, [numbers]);
return <div>Total: {total}</div>;
}
useCallback
import { useCallback, useState } from 'react';
function Parent() {
const [count, setCount] = useState(0);
// Only recreated when count changes
const handleClick = useCallback(() => {
console.log("Clicked", count);
}, [count]);
return <Child onClick={handleClick} />;
}
// React.memo – prevent re‑rendering if props unchanged
const Child = React.memo(({ onClick }) => {
console.log("Child rendered");
return <button onClick={onClick}>Click</button>;
});
Context API
// Create context const ThemeContext = React.createContext('light'); // Provider function App() { const [theme, setTheme] = useState('light'); return ( <ThemeContext.Provider value={{ theme, setTheme }}> <Toolbar /> </ThemeContext.Provider> ); } // Consumer (useContext hook) function Toolbar() { const { theme, setTheme } = useContext(ThemeContext); return ( <div style={{ background: theme === 'dark' ? '#333' : '#fff' }}> <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}> Toggle Theme </button> </div> ); }
Event Handling
function Button() {
// Basic handler
const handleClick = (event) => {
console.log("Clicked!", event);
};
// With parameter
const handleDelete = (id) => {
console.log("Deleting:", id);
};
return (
<div>
<button onClick={handleClick}>Click</button>
<button onClick={() => handleDelete(123)}>Delete</button>
// Form submit (prevent default)
<form onSubmit={(e) => {
e.preventDefault();
console.log("Submitted");
}}>
<input type="text" />
<button type="submit">Submit</button>
</form>
</div>
);
}
Conditional Rendering
// If with ternary function Greeting({ isLoggedIn }) { return ( <div> {isLoggedIn ? <LogoutButton /> : <LoginButton />} </div> ); } // If with logical && (render if true) function Notification({ message }) { return <div>{message && <p>{message}</p>}</div>; } // Early return function User({ user }) { if (!user) return <p>Loading...</p>; return <p>Hello, {user.name}</p>; }
Lists & Keys
function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}
// Keys should be stable, unique, and predictable
// Use id from data, not array index (unless list is static)
Forms (Controlled Components)
import { useState } from 'react';
function LoginForm() {
const [formData, setFormData] = useState({
email: '',
password: '',
remember: false
});
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setFormData(prev => ({
...prev,
[name]: type === 'checkbox' ? checked : value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log("Form data:", formData);
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="Email"
/>
<input
type="password"
name="password"
value={formData.password}
onChange={handleChange}
placeholder="Password"
/>
<label>
<input
type="checkbox"
name="remember"
checked={formData.remember}
onChange={handleChange}
/>
Remember me
</label>
<button type="submit">Login</button>
</form>
);
}
React Router
import { BrowserRouter, Routes, Route, Link, useParams, useNavigate } from 'react-router-dom';
// Setup
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/users">Users</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/users" element={<Users />} />
<Route path="/users/:id" element={<UserDetail />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
// Using params
function UserDetail() {
const { id } = useParams();
return <p>User ID: {id}</p>;
}
// Navigation
function Profile() {
const navigate = useNavigate();
return (
<button onClick={() => navigate('/settings')}>
Go to Settings
</button>
);
}
// Navigation with state
navigate('/profile', { state: { userId: 123 } });
Custom Hooks
// useLocalStorage function useLocalStorage(key, initialValue) { const [value, setValue] = useState(() => { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : initialValue; }); useEffect(() => { localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue]; } // Usage function App() { const [name, setName] = useLocalStorage('name', 'Guest'); return <input value={name} onChange={(e) => setName(e.target.value)} />; } // useFetch function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(url) .then(res => res.json()) .then(data => { setData(data); setLoading(false); }) .catch(err => { setError(err); setLoading(false); }); }, [url]); return { data, loading, error }; }
Styling
Inline Styles
const style = {
color: 'red',
fontSize: '16px',
fontWeight: 'bold'
};
<div style={style}>Content</div>
CSS Modules
// Component.module.css .container { display: flex; } .title { font-size: 24px; } // Component.jsx import styles from './Component.module.css'; <div className={styles.container}> <h1 className={styles.title}>Title</h1> </div>
Styled Components
import styled from 'styled-components';
const Button = styled.button`
background: ${props => props.primary ? 'blue' : 'gray'};
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
opacity: 0.8;
}
`;
<Button primary>Click me</Button>
useReducer
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
case 'RESET':
return { count: 0 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
<button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
</div>
);
}
Best Practices
- Use functional components and hooks – class components are legacy.
- Keep components small and focused on a single responsibility.
- Use
useMemoanduseCallbackfor expensive calculations and stable callbacks. - Use
React.memoto prevent unnecessary re‑renders of pure components. - Use
useEffectwith proper dependency arrays to avoid infinite loops. - Avoid inline functions in render for performance (use
useCallback). - Use
keycorrectly in lists – use stable, unique IDs. - Keep state as low as possible – avoid global state unless necessary.
- Use
Contextfor themes, user data, and other global state. - Use
React.StrictModeto catch potential issues. - Write tests using
React Testing Library. - Use
eslint-plugin-reactfor best practices and linting. - Use
prop-typesorTypeScriptfor type safety. - Use
lazyandSuspensefor code splitting. - Use
React Developer Toolsfor debugging.
📌 Quick Reference
Create React App:
Start dev server:
Build for production:
Install React Router:
npx create-react-app my-appStart dev server:
npm startBuild for production:
npm run buildInstall React Router:
npm install react-router-dom