React Cheatsheet
Components and JSX
Use this React reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
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 );