React SME Cookbook
All FAQs

Search Documentation

Search across all documentation pages

All FAQs

284 pages across 29 sections. 3278 questions total.

Sections

React Fundamentals(7 pages)


What is the difference between JSX and TSX?

TSX is JSX inside .tsx files with TypeScript type-checking enabled. The syntax is identical, but TSX validates prop types, expression types, and event handler types at compile time.

Why do I have to use className instead of class?

class is a reserved keyword in JavaScript. JSX compiles to JavaScript function calls, so React uses className to avoid the conflict. Using class triggers a console warning.

What can go inside curly braces in JSX?

Any valid JavaScript expression — variables, ternaries, function calls, template literals, and array methods like .map(). Statements like if/else or for loops cannot go directly inside {}.

When should I use a Fragment instead of a div?

Use <>...</> when you need to return multiple sibling elements without adding an extra DOM node. Use <Fragment key={...}> when mapping a list that needs keys on the wrapper.

How does the style prop work in JSX?

The style prop accepts a JavaScript object with camelCase properties, not a CSS string:

<div style={{ backgroundColor: "red", fontSize: 16 }} />
Can I use if/else inside JSX?

Not directly. Use a ternary expression {condition ? <A /> : <B />} or extract the logic into a variable before the return statement.

What does the spread operator do on a JSX element?

<Button {...props} /> passes all properties of the props object as individual attributes to the component. This is useful for forwarding props or extending native HTML elements.

How do I write comments inside JSX?

Use {/* comment */} inside JSX. HTML-style <!-- --> comments do not work and will cause a syntax error.

What is React.ReactNode vs React.JSX.Element?
  • React.ReactNode is the broadest type — includes JSX, strings, numbers, null, undefined, and arrays
  • React.JSX.Element is a single JSX element only, no strings or null
  • Use ReactNode for children props and JSX.Element for function return types that always return JSX
Why does JSX require a single root element?

JSX expressions compile to a single function call like React.createElement(...). Multiple adjacent elements would be multiple return values, which JavaScript doesn't support. Wrap siblings in a Fragment or a container element.

How do I render raw HTML strings in JSX?

Use dangerouslySetInnerHTML={{ __html: htmlString }}. Only use this with sanitized, trusted content — it bypasses React's XSS protections.

What happens when I render false, null, or undefined in JSX?

They render nothing. This is why {condition && <Component />} works — when condition is false, false renders as empty. However, 0 renders as the text "0".

What is the difference between a component and a regular function?

A component is a function that returns React.ReactNode (JSX, null, string, etc.) and is called by React during rendering. Regular functions are called by your code. Components must start with an uppercase letter so JSX treats them as components, not HTML elements.

Should I use an interface or type for props?

Prefer interface for component props. Interfaces produce better TypeScript error messages and support declaration merging. Use type only when you need union types or mapped types.

How do I set default values for props?

Use destructuring defaults in the function signature:

function Button({ variant = "primary" }: ButtonProps) {
  return <button className={variant}>Click</button>;
}
What is the children prop and when should I use it?

children is a special prop containing whatever JSX is nested between a component's opening and closing tags. Type it as React.ReactNode. Use it for wrapper/layout components that don't know their content in advance.

Can I define a component inside another component?

Technically yes, but don't. React creates a new component identity each render, destroying all state in the inner component. Always define components at the module level.

What is the slot pattern for components?

Instead of a single children prop, accept multiple named props typed as React.ReactNode:

function Layout({ header, sidebar, children }: LayoutProps) {
  return (
    <div>
      <header>{header}</header>
      <aside>{sidebar}</aside>
      <main>{children}</main>
    </div>
  );
}
When should I extract a new component?
  • When a piece of JSX is used in multiple places
  • When a section of a component has its own state or logic
  • When a component file exceeds ~150 lines and has clear boundaries
  • Don't extract prematurely — wait until you use a pattern at least three times
How do I extend native HTML element props in my component?

Use React.ComponentPropsWithoutRef<"element">:

interface ButtonProps extends React.ComponentPropsWithoutRef<"button"> {
  variant?: "primary" | "secondary";
}
What causes a component to re-render?
  • Its parent re-renders
  • Its own state changes (via useState or useReducer)
  • A context it consumes changes
  • Props changing alone doesn't trigger a re-render — the parent re-rendering does
What is a container component vs a presentational component?
  • Container components own state, fetch data, and handle logic
  • Presentational components receive data via props and focus on rendering UI
  • This separation keeps components focused and testable, though it's a guideline, not a strict rule
How do React Server Components differ from regular function components?

Server Components run only on the server, can await data directly, have zero client-side JavaScript, and cannot use hooks or event handlers. Regular (client) components run in the browser and support interactivity.

What is React.PropsWithChildren and when do I use it?

A utility type that adds children?: React.ReactNode to your props type:

type CardProps = React.PropsWithChildren<{ title: string }>;

Use it when you want a shorthand instead of manually typing children.

What is the best way to conditionally render a component?

Use a ternary {condition ? <A /> : <B />} to choose between two elements, or {condition && <A />} to show or hide one element. For complex multi-branch logic, use a variable or lookup object before the return.

Why does `0 && Component` render "0" on screen?

JavaScript's && operator returns the first falsy value. 0 is falsy but is a valid React child that renders as text. Use {count > 0 && <Component />} or a ternary instead.

When should I use early return vs ternary?
  • Early return for guarding the entire component (loading, error, not-found states)
  • Ternary for inline switches within the JSX tree
  • Early returns are more readable when there are multiple guard conditions
What is the lookup object pattern for conditional rendering?

Map state values to JSX elements using a Record:

const statusUI: Record<Status, React.ReactNode> = {
  idle: <p>Waiting...</p>,
  loading: <Spinner />,
  success: <DataTable />,
  error: <ErrorBanner />,
};
return <div>{statusUI[status]}</div>;
Does conditional rendering unmount and remount components?

Yes, if the component type at a tree position changes (e.g., <Spinner /> to <DataTable />), React unmounts the old component and mounts a new one, destroying all state. If only props change on the same component type, React updates in place.

How do I preserve state when toggling between two views?
  • Render both and toggle visibility with CSS display: none
  • Lift the state up to a parent component that persists across both views
  • Use a shared state store like Zustand
What is a discriminated union and how does it help conditional rendering?

A TypeScript union where each member has a literal status field. The switch or if on status narrows the type, so TypeScript knows which fields are available in each branch — eliminating undefined checks.

Is it bad to use nested ternaries?

Yes, they're hard to read. For more than two branches, extract the logic into a variable, use a switch statement, or use the lookup object pattern.

When should I use CSS display:none vs conditional rendering?
  • Use display: none when you want to keep the component mounted and preserve its state (e.g., tab panels)
  • Use conditional rendering when the hidden content is expensive to render, fetches data, or runs effects you want to stop
How do I render nothing from a component?

Return null. This is cleaner than returning an empty Fragment <></> and is the standard pattern for components that conditionally have no output.

Can I use switch statements in JSX?

Not directly inside JSX. Extract it to a variable or a helper function:

function getStatusIcon(status: Status) {
  switch (status) {
    case "success": return <CheckIcon />;
    case "error": return <XIcon />;
    default: return null;
  }
}
return <div>{getStatusIcon(status)}</div>;
Why does React need a key prop on list items?

Keys tell React which item is which across re-renders. Without stable keys, React cannot correctly match old and new elements, leading to lost state, broken animations, and incorrect DOM reuse.

Is it ever okay to use array index as a key?

Only for static lists that never reorder, filter, or have items inserted/removed. For any dynamic list, use a stable unique ID from your data (database ID, UUID, or slug).

What happens if two siblings have the same key?

React silently drops one of them, causing unpredictable behavior. Always ensure keys are unique among siblings. Combine fields if needed: key={`${item.type}-${item.id}`}.

How do I render a list with filter and sort?

Chain .filter() and .sort() before .map(). Wrap in useMemo if the list is large:

const visible = useMemo(
  () => items.filter(i => i.active).sort((a, b) => a.name.localeCompare(b.name)),
  [items]
);
return <ul>{visible.map(i => <li key={i.id}>{i.name}</li>)}</ul>;
How do I immutably add, remove, or update items in a list?
  • Add: setItems(prev => [...prev, newItem])
  • Remove: setItems(prev => prev.filter(i => i.id !== id))
  • Update: setItems(prev => prev.map(i => i.id === id ? { ...i, done: true } : i))
Where should the key prop go — on the outer or inner element?

Always on the outermost element returned by the .map() callback. Placing it on an inner child element has no effect.

Why is Math.random() a bad key?

It generates a new value every render, so React treats every item as new — unmounting and remounting all components each time. This destroys state and kills performance.

How do I handle an empty list?

Check items.length === 0 and render a placeholder message. An empty array renders nothing, which can look like a broken UI.

How do I use Fragment with a key in a list?

Import Fragment from React and use the named syntax:

import { Fragment } from "react";
{items.map(item => (
  <Fragment key={item.id}>
    <dt>{item.term}</dt>
    <dd>{item.definition}</dd>
  </Fragment>
))}

The short syntax <> does not support keys.

How can I force a component to reset its state using key?

Change the key to a new value. React unmounts the old component and mounts a fresh one with initial state:

<PlayerProfile key={currentPlayerId} playerId={currentPlayerId} />
When should I virtualize a list?

When rendering more than a few hundred items causes visible jank. Use @tanstack/react-virtual to only render items currently in the viewport, keeping DOM size small.

What is a SyntheticEvent in React?

A cross-browser wrapper around the native DOM event. React creates a SyntheticEvent for every event handler, normalizing browser differences. Access the native event via e.nativeEvent if needed.

What is the difference between e.target and e.currentTarget?
  • e.currentTarget — the element the handler is attached to
  • e.target — the element that actually triggered the event (may be a child)
  • Use currentTarget when reading attributes of the element you attached the handler to
Why does onClick=\{handleClick()\} call the function immediately?

Adding () invokes the function during render and passes its return value as the handler. Pass the reference instead: onClick={handleClick} or wrap it: onClick={() => handleClick(arg)}.

How do I pass data to an event handler?

Wrap the handler in an arrow function:

<button onClick={() => deleteItem(item.id)}>Delete</button>
How do I prevent a form from reloading the page on submit?

Call e.preventDefault() in the onSubmit handler:

<form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
How do I type an event handler in TypeScript?

Use the React event types with the HTML element generic:

function handleClick(e: React.MouseEvent<HTMLButtonElement>) { ... }
function handleChange(e: React.ChangeEvent<HTMLInputElement>) { ... }
function handleSubmit(e: React.FormEvent<HTMLFormElement>) { ... }
Does React onChange fire on every keystroke?

Yes. React's onChange behaves like the native input event, firing on every keystroke — not on blur like the native change event. This is by design for real-time form updates.

How do I stop an event from bubbling to parent handlers?

Call e.stopPropagation() in the child's event handler. For the capture phase (top-down), use onClickCapture instead of onClick.

Do arrow functions in onClick cause performance problems?

In most cases, no. The inline arrow creates a new function each render, which can defeat React.memo on child components. Only optimize with useCallback in hot paths like large lists.

How do I listen for keyboard shortcuts or window-level events?

Use useEffect with addEventListener on window or document:

useEffect(() => {
  const handler = (e: KeyboardEvent) => {
    if (e.key === "Escape") closeModal();
  };
  window.addEventListener("keydown", handler);
  return () => window.removeEventListener("keydown", handler);
}, []);
How do I type a handler prop passed to a child component?

Type it as a function accepting the data you need:

interface Props {
  onSearch: (query: string) => void;
}

Or use React's built-in handler type: React.MouseEventHandler<HTMLButtonElement>.

What is the difference between controlled and uncontrolled inputs?
  • Controlled: React state drives the input via value + onChange — React is the source of truth
  • Uncontrolled: The DOM holds the value via defaultValue — read it on demand with a ref or FormData
  • Use controlled for real-time validation; uncontrolled for simple forms or performance-sensitive inputs
What are React 19 form actions?

You can pass an async function directly to <form action={fn}>. React calls it with a FormData object on submit, handles the pending state, and integrates with useActionState for managing return values — no e.preventDefault() needed.

What is useActionState and how does it work?

useActionState(actionFn, initialState) returns [state, formAction, isPending]. On submit, it calls actionFn(prevState, formData) and updates state with the result. isPending is true while the action runs.

Why is my controlled input read-only?

Setting value without an onChange handler makes the input uneditable — React locks the value to state. Either add onChange to update state, or switch to defaultValue for an uncontrolled input.

Why doesn't changing defaultValue update my input?

defaultValue only sets the initial DOM value on mount. Changes after mount have no effect. Use controlled value if React needs to drive updates, or add a key prop to force remount.

How do I handle checkboxes and radio buttons?

Use checked / defaultChecked instead of value / defaultValue:

<input
  type="checkbox"
  checked={isEnabled}
  onChange={e => setIsEnabled(e.target.checked)}
/>
How do I get a number from a number input?

e.target.value is always a string, even for <input type="number">. Parse it explicitly: Number(e.target.value) or parseInt(e.target.value, 10).

What is useFormStatus and where can I use it?

useFormStatus() returns { pending } to show loading state during a form action. It must be called in a component that is a child of a <form> — not in the same component that renders the form.

How do I handle multiple form fields without separate useState for each?

Use a single state object and a generic update function:

const [form, setForm] = useState({ name: "", email: "" });
function updateField(field: string, value: string) {
  setForm(prev => ({ ...prev, [field]: value }));
}
When should I use a form library like React Hook Form instead?
  • More than 3-5 fields with validation rules
  • Complex interdependent validation (field B depends on field A)
  • Performance-critical forms where re-renders per keystroke matter
  • For simple forms with 1-3 fields, plain controlled inputs or form actions are sufficient
How do I implement optimistic updates with forms in React 19?

Use useOptimistic to immediately show the expected result while the action processes. If the action fails, React reverts to the actual state automatically.

How do I make forms accessible?
  • Pair every input with a <label htmlFor="id"> matching the input's id
  • Use required, aria-describedby for error messages, and aria-invalid for invalid fields
  • Ensure error messages are announced to screen readers
What is useRef and when should I use it?

useRef returns a mutable object { current: value } that persists across renders without causing re-renders. Use it for DOM access (focus, scroll, measure), storing timer IDs, and keeping mutable values that the UI doesn't depend on.

What is the difference between useRef and useState?
  • useState triggers a re-render when updated — use for values the UI displays
  • useRef does not trigger re-renders — use for values like timer IDs, previous values, or DOM nodes
Why is ref.current null on the first render?

DOM refs are populated after React mounts the element. During render, the DOM node doesn't exist yet. Access refs in event handlers, useEffect, or behind a null check: ref.current?.focus().

Do I still need forwardRef in React 19?

No. In React 19, ref is a regular prop. Accept it directly:

function Input({ ref, ...props }: { ref?: React.Ref<HTMLInputElement> }) {
  return <input ref={ref} {...props} />;
}
What is a ref callback and how is it different from useRef?

A ref callback is a function passed to the ref prop. React calls it with the DOM node on mount and null on unmount. In React 19, it can return a cleanup function. Use it when you need setup/teardown logic tied to the DOM node (like ResizeObserver).

How do I store a timer ID with useRef?
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
timerRef.current = setInterval(() => { ... }, 1000);
// Later:
clearInterval(timerRef.current!);

This avoids stale closure issues since ref.current always points to the latest value.

What is useImperativeHandle?

It lets you customize the value exposed when a parent uses a ref on your component. Instead of exposing the raw DOM node, you expose a limited API like { open(), close() }. Use sparingly — prefer props for most communication.

Can I use useRef to track how many times a component has rendered?

Yes. Increment ref.current in the component body:

const renderCount = useRef(0);
renderCount.current += 1;

Since ref changes don't trigger re-renders, this won't cause an infinite loop.

Why does my ref callback fire twice in StrictMode?

React's StrictMode simulates unmount/remount in development, so the ref callback fires with null then the node. This is expected. In React 19, return a cleanup function from the ref callback instead of checking for null.

How do I create a usePrevious custom hook with useRef?
function usePrevious<T>(value: T): T | undefined {
  const ref = useRef<T | undefined>(undefined);
  useEffect(() => { ref.current = value; }, [value]);
  return ref.current;
}

The ref stores the old value because useEffect runs after render.