React Cheatsheet
Components and JSX
Use this React reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Function Components
The only modern component type. A function that accepts props and returns JSX (or null).
// Declaration function Button({ label, onClick }) { return <button onClick={onClick}>{label}</button>; } // Arrow function const Button = ({ label, onClick }) => ( <button onClick={onClick}>{label}</button> ); // Arrow with block body (needed for multiple statements) const Button = ({ label, onClick }) => { const cls = label.length > 10 ? 'long' : 'short'; return <button className={cls} onClick={onClick}>{label}</button>; };
JSX Expressions and Embedding Values
const name = 'Alice'; const count = 42; const isAdmin = true; function Profile() { return ( <div> {/* strings, numbers, expressions */} <p>{name}</p> <p>{count * 2}</p> <p>{isAdmin ? 'Admin' : 'User'}</p> {/* function calls */} <p>{name.toUpperCase()}</p> {/* arrays render each element */} <ul>{['a', 'b', 'c'].map(x => <li key={x}>{x}</li>)}</ul> {/* null, undefined, false, true render nothing */} {false} {null} {undefined} {/* objects are NOT valid children — use JSON.stringify or access a property */} {/* WRONG: {myObj} */} {JSON.stringify({ a: 1 })} </div> ); }
Fragments
Wrap multiple siblings without adding a DOM node.
import { Fragment } from 'react'; // Short syntax (no props) function Row() { return ( <> <td>Name</td> <td>Age</td> </> ); } // Long form — needed when passing key to the fragment function List({ items }) { return items.map(item => ( <Fragment key={item.id}> <dt>{item.term}</dt> <dd>{item.def}</dd> </Fragment> )); }
JSX Attribute Rules
| HTML attribute | JSX equivalent |
|---|---|
class | className |
for | htmlFor |
tabindex | tabIndex |
readonly | readOnly |
maxlength | maxLength |
crossorigin | crossOrigin |
enctype | encType |
onclick | onClick |
style="color:red" | style={{ color: 'red' }} |
checked (static) | defaultChecked (uncontrolled) |
value (static) | defaultValue (uncontrolled) |
// Spreading an object as props const attrs = { id: 'btn', disabled: true, 'aria-label': 'Save' }; const el = <button {...attrs}>Save</button>; // aria-* and data-* use their original kebab-case names const el2 = <div aria-hidden="true" data-testid="box" />;
Children
// children prop — anything between opening and closing tags function Card({ children, title }) { return ( <div className="card"> <h2>{title}</h2> {children} </div> ); } // Usage <Card title="Info"> <p>Some content</p> <p>More content</p> </Card> // Children utilities — LEGACY: react.dev discourages Children.* and // cloneElement (fragile, break with Fragments/wrappers). Prefer passing // props/JSX explicitly, render props, or context. Shown for reading old code: import { Children, cloneElement, isValidElement } from 'react'; Children.count(children) // number of children Children.toArray(children) // flat array, keys reassigned Children.map(children, fn) // map without losing keys Children.forEach(children, fn) // iterate Children.only(children) // assert exactly one child, return it isValidElement(obj) // true if obj is a React element // Clone and inject extra props cloneElement(element, { extraProp: 'value' })
Composition Patterns
// Slot pattern via named props function Layout({ header, sidebar, children }) { return ( <div className="layout"> <header>{header}</header> <aside>{sidebar}</aside> <main>{children}</main> </div> ); } // Usage <Layout header={<nav>Nav</nav>} sidebar={<SideMenu />} > <PageContent /> </Layout> // Render props function Mouse({ render }) { const [pos, setPos] = useState({ x: 0, y: 0 }); return ( <div onMouseMove={e => setPos({ x: e.clientX, y: e.clientY })}> {render(pos)} </div> ); } <Mouse render={({ x, y }) => <p>{x}, {y}</p>} />
Lazy Loading Components
import { lazy, Suspense } from 'react'; // Dynamic import — code-split at this boundary const HeavyChart = lazy(() => import('./HeavyChart')); function Dashboard() { return ( <Suspense fallback={<p>Loading chart…</p>}> <HeavyChart /> </Suspense> ); }
Portals
Render children into a different DOM node outside the parent hierarchy.
import { createPortal } from 'react-dom'; function Modal({ children }) { return createPortal( <div className="modal-overlay">{children}</div>, document.getElementById('modal-root') // target DOM node ); }
Display Names and DevTools
// Named function declarations get a display name automatically function MyComponent() { return null; } // Arrow functions assigned to a const also infer the name const MyComponent = () => null; // Set explicitly (useful for HOCs and wrappers) const WrappedComponent = React.memo(MyComponent); WrappedComponent.displayName = 'WrappedMyComponent';
Strict Mode Behavior
import { StrictMode } from 'react'; // In development only: // - Renders components twice to detect side-effects in render // - Calls effects twice (mount → unmount → remount) to verify cleanup // - Warns about deprecated APIs // Has zero effect in production builds <StrictMode> <App /> </StrictMode>
ref as a Prop (React 19) and forwardRef (legacy)
Since React 19, function components receive ref as a regular prop — no wrapper needed.
// React 19 — just destructure ref like any other prop function FancyInput({ label, ref }) { return ( <label> {label} <input ref={ref} /> </label> ); } // Usage (identical in both patterns) function Form() { const inputRef = useRef(null); return <FancyInput label="Name" ref={inputRef} />; }
forwardRef is the React ≤18 pattern and is deprecated in React 19 (it still works, but new code should take ref as a prop):
// Legacy (React ≤18) — ref arrives as a second argument via forwardRef import { forwardRef } from 'react'; const FancyInput = forwardRef(function FancyInput({ label }, ref) { return ( <label> {label} <input ref={ref} /> </label> ); });
Error Boundaries
Catch render errors in a subtree and show a fallback instead of unmounting the whole app. Still class-only — there is no hook equivalent; most apps use the react-error-boundary package.
// Class implementation import { Component } from 'react'; class ErrorBoundary extends Component { state = { hasError: false }; static getDerivedStateFromError(error) { return { hasError: true }; // render the fallback next pass } componentDidCatch(error, info) { logError(error, info.componentStack); // report to your error service } render() { if (this.state.hasError) return this.props.fallback; return this.props.children; } } <ErrorBoundary fallback={<p>Something went wrong.</p>}> <Profile /> </ErrorBoundary>
// react-error-boundary (npm install react-error-boundary) import { ErrorBoundary } from 'react-error-boundary'; <ErrorBoundary fallbackRender={({ error, resetErrorBoundary }) => ( <div role="alert"> <pre>{error.message}</pre> <button onClick={resetErrorBoundary}>Try again</button> </div> )} onError={(error, info) => logError(error, info)} > <Profile /> </ErrorBoundary>
Error boundaries do not catch: event handler errors (use try/catch), async code, SSR errors, or errors thrown in the boundary itself. Place one near the root plus finer-grained ones around risky widgets.
memo — Skip Re-renders
import { memo } from 'react'; // Component only re-renders if props change (shallow comparison) const ExpensiveList = memo(function ExpensiveList({ items }) { return <ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>; }); // Custom comparison function (optional) const Item = memo( function Item({ data }) { return <div>{data.name}</div>; }, (prevProps, nextProps) => prevProps.data.id === nextProps.data.id );