React Cheatsheet
Props
Use this React reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Passing Props
Props are passed as JSX attributes and received as the first argument to the component function.
// Parent passes props <UserCard name="Alice" age={30} active={true} scores={[95, 87]} /> // Child receives props object function UserCard(props) { return <p>{props.name} — {props.age}</p>; } // Destructure in the parameter (most common) function UserCard({ name, age, active, scores }) { return <p>{name} — {age}</p>; }
Prop Types
Any JavaScript value can be a prop:
<Component str="hello" // string num={42} // number bool={true} // boolean (or just: <Component bool />) arr={[1, 2, 3]} // array obj={{ x: 1, y: 2 }} // object fn={() => console.log('clicked')} // function node={<span>JSX</span>} // React element ref={myRef} // ref — a regular prop since React 19 />
Default Props
// Default values via destructuring (preferred) function Button({ label = 'Click me', size = 'md', disabled = false }) { return <button disabled={disabled} className={`btn-${size}`}>{label}</button>; } // Calling component — defaults apply when prop is omitted or undefined <Button /> // label="Click me", size="md" <Button label="Save" /> // size="md", disabled=false <Button disabled /> // disabled={true}
Component.defaultPropswas removed for function components in React 19 — it is silently ignored. Use parameter destructuring defaults (above).defaultPropsstill works on class components only.
Spreading Props
// Spread an object onto a component const linkProps = { href: '/about', target: '_blank', rel: 'noreferrer' }; const el = <a {...linkProps}>About</a>; // Pass through all parent props to a child (forwarding / wrapper components) function FancyButton({ className, ...rest }) { return <button className={`fancy ${className}`} {...rest} />; } // Spread + override (later wins) <Button {...defaults} label="Override" />
PropTypes (legacy — removed in React 19)
React 19 removed propTypes checking from React itself: on function components, a propTypes object is silently ignored. Use TypeScript for type safety in current React. The pattern below only produces runtime warnings on React ≤18.
// React ≤18 only — silently ignored on function components in React 19 import PropTypes from 'prop-types'; // npm install prop-types function Avatar({ src, size, alt }) { return <img src={src} width={size} height={size} alt={alt} />; } Avatar.propTypes = { src: PropTypes.string.isRequired, size: PropTypes.number, alt: PropTypes.string, onClick: PropTypes.func, theme: PropTypes.oneOf(['light', 'dark']), user: PropTypes.shape({ id: PropTypes.number.isRequired, name: PropTypes.string, }), items: PropTypes.arrayOf(PropTypes.string), node: PropTypes.node, // anything renderable element: PropTypes.element, // React element any: PropTypes.any, };
Even on React ≤18, PropTypes only run in development. For real type safety use TypeScript (below).
TypeScript Prop Types
// Inline type function Button({ label, onClick }: { label: string; onClick: () => void }) { return <button onClick={onClick}>{label}</button>; } // Named interface (preferred for reuse) interface CardProps { title: string; subtitle?: string; // optional children: React.ReactNode; onClose: () => void; style?: React.CSSProperties; } function Card({ title, subtitle, children, onClose }: CardProps) { return ( <div> <h2>{title}</h2> {subtitle && <p>{subtitle}</p>} {children} <button onClick={onClose}>Close</button> </div> ); } // Type alias type ButtonProps = { variant: 'primary' | 'secondary' | 'danger'; size?: 'sm' | 'md' | 'lg'; disabled?: boolean; };
children Prop
// React.ReactNode — anything React can render function Wrapper({ children }: { children: React.ReactNode }) { return <div className="wrapper">{children}</div>; } // React.ReactElement — must be a single React element function SingleChild({ children }: { children: React.ReactElement }) { return React.cloneElement(children, { className: 'injected' }); } // Function as children (render prop) function Toggle({ children }: { children: (on: boolean) => React.ReactNode }) { const [on, setOn] = useState(false); return ( <> {children(on)} <button onClick={() => setOn(v => !v)}>Toggle</button> </> ); } <Toggle>{on => <span>{on ? 'ON' : 'OFF'}</span>}</Toggle>
Prop Drilling and When to Avoid It
// Prop drilling — passing through intermediaries that don't use it function Page({ user }) { return <Sidebar user={user} />; // Sidebar doesn't use user… } function Sidebar({ user }) { return <Avatar user={user} />; // …only Avatar does } function Avatar({ user }) { return <img src={user.avatar} alt={user.name} />; } // Solutions: // 1. Composition — pass rendered JSX instead of data function Page({ user }) { return <Sidebar avatar={<Avatar user={user} />} />; } function Sidebar({ avatar }) { return <aside>{avatar}</aside>; } // 2. Context (see Context page) // 3. State management library (Zustand, Redux Toolkit, Jotai…)
Immutability — Never Mutate Props
// WRONG — never mutate props function Bad({ items }) { items.push({ id: 99 }); // mutates the parent's array return <ul>{items.map(...)}</ul>; } // CORRECT — derive new values function Good({ items }) { const extended = [...items, { id: 99 }]; return <ul>{extended.map(...)}</ul>; }
Gotchas
// Boolean shorthand: <Input required /> is the same as <Input required={true} /> // Passing 0 as a prop still renders! Use !! or Boolean() to guard: {count && <Badge count={count} />} // renders "0" when count is 0! {count > 0 && <Badge count={count} />} // correct // Objects/arrays as default props — define outside the component to avoid // creating a new reference every render (breaks memo): const DEFAULT_OPTIONS = { size: 'md' }; function Input({ options = DEFAULT_OPTIONS }) { ... }