React Components & JSX
React components cheat sheet covering JSX syntax, props, conditional rendering, lists, event handling, and composition patterns.
Other React Sheets
Sign in to mark items as known and track your progress.
Sign inComponent Essentials
Core concepts for building React components
Function Components
Modern way to create React components
// Simple function component
function Welcome() {
return <h1>Hello, World!</h1>
}
// Arrow function syntax
const Welcome = () => {
return <h1>Hello, World!</h1>
}
// Using the component
function App() {
return (
<div>
<Welcome />
<Welcome />
</div>
)
}Basic Props
Pass data to components via props
// Component with props
function Greeting({ name, age }) {
return (
<div>
<h1>Hello, {name}!</h1>
<p>Age: {age}</p>
</div>
)
}
// Using with props
function App() {
return (
<div>
<Greeting name="Alice" age={25} />
<Greeting name="Bob" age={30} />
</div>
)
}Default Props
Set default values for optional props
// Default props with destructuring
function Button({
text,
color = 'blue',
size = 'medium'
}) {
return (
<button className={'btn-' + size} style={{ color }}>
{text}
</button>
)
}
// Some props use defaults, some don't
<Button text="Click me" />
<Button text="Submit" color="green" size="large" />Children Prop
Pass JSX content between component tags
// Component with children
function Card({ children, title }) {
return (
<div className="card">
<h2>{title}</h2>
<div className="content">
{children}
</div>
</div>
)
}
// Pass content as children
function App() {
return (
<Card title="User Info">
<p>Name: John Doe</p>
<p>Email: john@example.com</p>
<button>Edit</button>
</Card>
)
}Event Handlers
Handle user interactions with events
// Click event
function Button() {
const handleClick = () => {
alert('Clicked!')
}
return <button onClick={handleClick}>Click me</button>
}
// Event with parameters
function Item({ id, name, onDelete }) {
return (
<div>
<span>{name}</span>
<button onClick={() => onDelete(id)}>Delete</button>
</div>
)
}
// Using the component
function App() {
const handleDelete = (itemId) => {
console.log('Deleting:', itemId)
}
return <Item id={1} name="Task" onDelete={handleDelete} />
}Component Import/Export
Organize components in separate files
// Button.js - Export component
function Button({ text, onClick }) {
return <button onClick={onClick}>{text}</button>
}
export default Button
// App.js - Import and use
import Button from './Button'
function App() {
return (
<div>
<h1>My App</h1>
<Button text="Click me" onClick={() => alert('Hi!')} />
</div>
)
}Keeping Components Pure
Components must be pure functions of their props and state
// ❌ IMPURE — mutates external state
let count = 0;
function Counter() {
count++; // side effect during render
return <div>{count}</div>;
}
// ✅ PURE — same input, same output
function Counter({ count }) {
return <div>{count}</div>;
}JSX Fundamentals
JavaScript XML syntax for describing UI in React
JSX Basics
JavaScript XML syntax for React
// JSX looks like HTML but it's JavaScript
function Welcome() {
return <h1>Hello World</h1>
}
// Multi-line JSX needs parentheses
function Card() {
return (
<div className="card">
<h2>Title</h2>
<p>Content</p>
</div>
)
}
// JSX compiles to JavaScript
// <h1>Hi</h1> becomes React.createElement('h1', null, 'Hi')JSX Expressions
Embed JavaScript expressions in JSX
function UserCard() {
const name = 'Alice'
const age = 25
const isAdult = age >= 18
return (
<div>
{/* Variables */}
<h2>{name}</h2>
{/* Math expressions */}
<p>Age: {age + 1} next year</p>
{/* Ternary operator */}
<p>{isAdult ? 'Can vote' : 'Too young'}</p>
{/* Function calls */}
<p>Uppercase: {name.toUpperCase()}</p>
</div>
)
}JSX Attributes
HTML attributes in JSX use camelCase
function Form() {
return (
<div>
{/* className instead of class */}
<div className="container">
{/* htmlFor instead of for */}
<label htmlFor="name">Name:</label>
<input id="name" type="text" />
{/* camelCase attributes */}
<input
autoFocus
tabIndex={0}
placeholder="Enter text"
/>
{/* Event handlers are camelCase */}
<button onClick={() => alert('Hi!')}>
Click Me
</button>
</div>
</div>
)
}Inline Styles
Apply styles using JavaScript objects
function StyledComponent() {
const styles = {
color: 'blue',
fontSize: '20px',
backgroundColor: '#f0f0f0',
padding: '10px'
}
return (
<div>
{/* Style object */}
<h1 style={styles}>Styled heading</h1>
{/* Inline style object */}
<p style={{
color: 'red',
fontWeight: 'bold'
}}>
Inline styled text
</p>
{/* Dynamic styles */}
<div style={{
backgroundColor: true ? 'green' : 'red',
width: '100px',
height: '100px'
}} />
</div>
)
}Conditional Rendering
Show/hide elements based on conditions
function Notifications({ user, count }) {
return (
<div>
{/* Ternary operator */}
{user ? (
<h1>Welcome, {user.name}!</h1>
) : (
<h1>Please log in</h1>
)}
{/* Logical && operator */}
{count > 0 && (
<p>You have {count} new messages</p>
)}
{/* Logical || for defaults */}
<p>Name: {user?.name || 'Guest'}</p>
{/* Prevent rendering with null */}
{count === 0 ? null : <span>({count})</span>}
</div>
)
}Lists & Keys
Render arrays with map and unique keys
function TodoList() {
const todos = [
{ id: 1, text: 'Learn React' },
{ id: 2, text: 'Build an app' },
{ id: 3, text: 'Deploy it' }
]
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>
{todo.text}
</li>
))}
</ul>
)
}Fragments
Return multiple elements without wrapper
import { Fragment } from 'react'
// Long syntax with Fragment
function LongForm() {
return (
<Fragment>
<h1>Title</h1>
<p>Paragraph</p>
</Fragment>
)
}
// Short syntax (preferred)
function ShortForm() {
return (
<>
<h1>Title</h1>
<p>Paragraph</p>
</>
)
}
// Only Fragment can have key prop
function ListItems({ items }) {
return (
<>
{items.map(item => (
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.definition}</dd>
</Fragment>
))}
</>
)
}JSX Comments
Add comments in JSX code
function Comments() {
return (
<div>
{/* Single line comment */}
<h1>Title</h1>
{/*
Multi-line
comment
*/}
<p>Content</p>
{/* TODO: Add more content */}
{/* Conditional comment
{false && <p>This won't render</p>}
*/}
</div>
)
}
// Regular JS comments work outside JSX
// This is a normal comment
function Component() {
// Another normal comment
return <div>Content</div>
}Forms & Controlled Components
Build interactive forms with controlled and uncontrolled components
Controlled Inputs
Form inputs controlled by React state
function Form() {
const [name, setName] = React.useState('')
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter name"
/>
<p>Hello, {name}!</p>
</div>
)
}Form Submission
Handle form submit events
function LoginForm() {
const [email, setEmail] = React.useState('')
const [password, setPassword] = React.useState('')
const handleSubmit = (e) => {
e.preventDefault() // Prevent page reload
console.log('Login:', email, password)
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
<button type="submit">Login</button>
</form>
)
}Select & Textarea
Controlled select dropdowns and textareas
function Survey() {
const [country, setCountry] = React.useState('us')
const [comments, setComments] = React.useState('')
return (
<div>
{/* Controlled select */}
<select
value={country}
onChange={(e) => setCountry(e.target.value)}
>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca">Canada</option>
</select>
{/* Controlled textarea */}
<textarea
value={comments}
onChange={(e) => setComments(e.target.value)}
rows={4}
placeholder="Your comments..."
/>
<p>Selected: {country}</p>
<p>Comments: {comments}</p>
</div>
)
}Checkboxes & Radio
Handle checkbox and radio button inputs
function Preferences() {
const [subscribe, setSubscribe] = React.useState(false)
const [frequency, setFrequency] = React.useState('weekly')
return (
<div>
{/* Checkbox */}
<label>
<input
type="checkbox"
checked={subscribe}
onChange={(e) => setSubscribe(e.target.checked)}
/>
Subscribe to newsletter
</label>
{/* Radio buttons */}
<div>
<label>
<input
type="radio"
value="daily"
checked={frequency === 'daily'}
onChange={(e) => setFrequency(e.target.value)}
/>
Daily
</label>
<label>
<input
type="radio"
value="weekly"
checked={frequency === 'weekly'}
onChange={(e) => setFrequency(e.target.value)}
/>
Weekly
</label>
</div>
</div>
)
}Context API
Share data across components without prop drilling
Context API
Create, provide, and consume context with createContext and useContext
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext('light');
function App() {
const [theme, setTheme] = useState('dark');
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <div className={theme}>Toolbar</div>;
}Component Patterns & Types
Advanced patterns for type safety and component composition
Composition with children
Use the children prop to build flexible, composable layout components
function Card({ children }) {
return <div className="card">{children}</div>;
}
function App() {
return (
<Card>
<h2>Title</h2>
<p>Content</p>
</Card>
);
}PropTypes & TypeScript
Add type checking to React components
// TypeScript (recommended) - compile-time prop checking
interface UserProps {
name: string
age?: number
email: string
}
function User({ name, age = 0, email }: UserProps) {
return <div>{name}, {age}, {email}</div>
}
// React 19 removed runtime propTypes - assigning User.propTypes
// is now ignored. For runtime validation, use a schema like Zod.Refs & forwardRef
Access DOM elements and pass refs through components
// Basic ref - access a DOM node imperatively
function TextInput() {
const inputRef = useRef(null)
const focusInput = () => {
inputRef.current.focus()
}
return (
<div>
<input ref={inputRef} />
<button onClick={focusInput}>Focus Input</button>
</div>
)
}
// React 19: ref is a regular prop - no forwardRef needed
function FancyInput({ ref, ...props }) {
return <input ref={ref} className="fancy-input" {...props} />
}Compound Components
Build flexible APIs with related components that share state
function Tabs({ children, defaultTab }) {
const [active, setActive] = useState(defaultTab);
return (
<TabsContext.Provider value={{ active, setActive }}>
{children}
</TabsContext.Provider>
);
}
Tabs.List = TabList;
Tabs.Tab = Tab;
Tabs.Panel = TabPanel;Higher-Order Components (HOCs)
Functions that take a component and return an enhanced component
function withLogger(Component) {
return function Wrapped(props) {
console.log('Rendering', Component.name, props);
return <Component {...props} />;
};
}
const LoggedButton = withLogger(Button);Render Props
Share logic by passing a render function as a prop
function MouseTracker({ render }) {
const [pos, setPos] = useState({ x: 0, y: 0 });
useEffect(() => {
const move = (e) => setPos({ x: e.clientX, y: e.clientY });
window.addEventListener('mousemove', move);
return () => window.removeEventListener('mousemove', move);
}, []);
return render(pos);
}
<MouseTracker render={({ x, y }) => <p>{x}, {y}</p>} />Optimization & Advanced Features
Performance optimization and advanced React features
Suspense & lazy()
Code-split components and show fallback UI while loading
import { lazy, Suspense } from 'react';
const HeavyChart = lazy(() => import('./HeavyChart'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyChart />
</Suspense>
);
}Error Boundaries
Catch render errors in child components and show fallback UI
class ErrorBoundary extends Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.error(error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}React.memo & Optimization
Optimize component re-renders with memoization
// React.memo
const ExpensiveComponent = React.memo(function Component({ data }) {
return <div>{data.value}</div>
})
// Custom comparison
const MyComponent = React.memo(Component, (prevProps, nextProps) => {
// Return true if props are equal (skip re-render)
return prevProps.id === nextProps.id
})Styling Components
Different approaches to styling React components
// Inline Styles
<div style={{ backgroundColor: 'blue', padding: '10px' }}>
Inline styled
</div>
// CSS Classes
<div className="card primary-card">
CSS Classes
</div>
// CSS Modules
import styles from './Component.module.css'
<div className={styles.card}>CSS Module</div>
// Styled Components
import styled from 'styled-components'
const Button = styled.button`
background: ${props => props.primary ? 'blue' : 'gray'};
color: white;
padding: 10px;
`Portals (createPortal)
Render children into a different DOM node outside the parent hierarchy
import { createPortal } from 'react-dom';
function Modal({ children, onClose }) {
return createPortal(
<div className="modal-overlay" onClick={onClose}>
<div className="modal">{children}</div>
</div>,
document.body
);
}StrictMode
Catch bugs early by enabling extra development checks
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
);