[{"data":1,"prerenderedAt":446},["ShallowReactive",2],{"topic-react-components":3},{"framework":4,"topic":15,"subtopics":23},{"id":5,"description":6,"extension":7,"icon":8,"meta":9,"name":10,"order":11,"slug":8,"stem":12,"tier":13,"__hash__":14},"frameworks\u002Fframeworks\u002Freact.yml","React interview questions on hooks, components, state and rendering — the most-requested front-end framework in technical interviews.","yml","react",{},"React",2,"frameworks\u002Freact",1,"RA6wemU0xFHrA1ZKCABP1J7MireA3Bt_FCJMOuMgsm0",{"id":16,"description":17,"extension":7,"frameworkSlug":8,"meta":18,"name":19,"order":11,"slug":20,"stem":21,"__hash__":22},"topics\u002Ftopics\u002Freact-components.yml","JSX syntax, props, event handling, conditional rendering, and lists — the building blocks of every React UI.",{},"Components","components","topics\u002Freact-components","H4Z8kPxOMQnuMfHulzl4Rb9l7Vu6AndqtV3k7T-p4jE",[24,113,194,279,356],{"id":25,"title":26,"body":27,"description":31,"difficulty":33,"extension":34,"framework":10,"frameworkSlug":8,"meta":35,"navigation":37,"order":13,"path":38,"questions":39,"questionsCount":105,"related":106,"seo":107,"seoDescription":108,"stem":109,"subtopic":110,"topic":19,"topicSlug":20,"updated":111,"__hash__":112},"qa\u002Freact\u002Fcomponents\u002Fjsx-rendering.md","Jsx Rendering",{"type":28,"value":29,"toc":30},"minimark",[],{"title":31,"searchDepth":11,"depth":11,"links":32},"",[],"easy","md",{"subtopicSlug":36},"jsx-rendering",true,"\u002Freact\u002Fcomponents\u002Fjsx-rendering",[40,44,48,52,56,61,65,69,73,77,81,85,89,93,97,101],{"id":41,"difficulty":33,"q":42,"a":43},"what-is-jsx","What is JSX and what does React do with it?","**JSX** is a syntax extension to JavaScript that lets you write HTML-like\nmarkup inside a `.js` or `.tsx` file. It is **not** valid JavaScript — a\nbuild tool (Babel, SWC, or the TypeScript compiler) transforms every JSX\nexpression into a `React.createElement` call before the browser sees it.\n\n```jsx\n\u002F\u002F What you write\nconst el = \u003Ch1 className=\"title\">Hello\u003C\u002Fh1>\n\n\u002F\u002F What the compiler produces (React 17+ JSX transform uses _jsx instead)\nconst el = React.createElement('h1', { className: 'title' }, 'Hello')\n```\n\nThe output is a plain JavaScript object — a **React element** — that\ndescribes what should appear on screen. React's renderer later turns that\ndescription into actual DOM nodes.\n\n**Rule of thumb:** JSX is syntactic sugar for `React.createElement`. If you\ncan't picture the compiled form, you don't yet fully understand what JSX is.\n",{"id":45,"difficulty":33,"q":46,"a":47},"jsx-single-root","Why must JSX always return a single root element?","Because JSX compiles to a single `React.createElement` call, which returns\none value. You can't return two values from one expression in JavaScript.\n\n```jsx\n\u002F\u002F ❌ Invalid — two adjacent elements at the top level\nreturn (\n  \u003Ch1>Title\u003C\u002Fh1>\n  \u003Cp>Body\u003C\u002Fp>\n)\n\n\u002F\u002F ✅ Wrap in a div\nreturn (\n  \u003Cdiv>\n    \u003Ch1>Title\u003C\u002Fh1>\n    \u003Cp>Body\u003C\u002Fp>\n  \u003C\u002Fdiv>\n)\n\n\u002F\u002F ✅ Or use a Fragment (no extra DOM node)\nreturn (\n  \u003C>\n    \u003Ch1>Title\u003C\u002Fh1>\n    \u003Cp>Body\u003C\u002Fp>\n  \u003C\u002F>\n)\n```\n\n**Rule of thumb:** when you need siblings without a wrapper DOM node, reach\nfor a Fragment (`\u003C>…\u003C\u002F>` or `\u003CReact.Fragment>…\u003C\u002FReact.Fragment>`).\n",{"id":49,"difficulty":33,"q":50,"a":51},"fragments","What are React Fragments and when should you use them?","A **Fragment** groups children without adding an extra node to the DOM.\nThere are two syntaxes:\n\n```jsx\n\u002F\u002F Short syntax — most common\nreturn (\n  \u003C>\n    \u003Cdt>Term\u003C\u002Fdt>\n    \u003Cdd>Definition\u003C\u002Fdd>\n  \u003C\u002F>\n)\n\n\u002F\u002F Long syntax — required when you need the key prop (e.g. in a list)\nreturn items.map(item => (\n  \u003CReact.Fragment key={item.id}>\n    \u003Cdt>{item.term}\u003C\u002Fdt>\n    \u003Cdd>{item.def}\u003C\u002Fdd>\n  \u003C\u002FReact.Fragment>\n))\n```\n\nUse Fragments when:\n- A wrapper `\u003Cdiv>` would break CSS layout (e.g. inside a `\u003Ctable>` or\n  flex\u002Fgrid container).\n- You're mapping over pairs of sibling elements that each need a `key`.\n\n**Rule of thumb:** prefer `\u003C>…\u003C\u002F>` by default; switch to the named form\nonly when you need to attach `key`.\n",{"id":53,"difficulty":33,"q":54,"a":55},"jsx-expressions","How do you embed JavaScript expressions in JSX?","Wrap any JavaScript **expression** in `{}`. An expression is anything that\nproduces a single value — a variable, function call, ternary, template\nliteral, etc.\n\n```jsx\nconst name = 'Alice'\nconst isAdmin = true\n\nreturn (\n  \u003Cdiv>\n    \u003Cp>Hello, {name.toUpperCase()}\u003C\u002Fp>\n    \u003Cp>Role: {isAdmin ? 'Admin' : 'User'}\u003C\u002Fp>\n    \u003Cp>Sum: {2 + 2}\u003C\u002Fp>\n  \u003C\u002Fdiv>\n)\n```\n\n**What you cannot put in `{}`:**\n- Statements (`if`, `for`, variable declarations) — they don't produce a\n  value. Extract them above the return, or use expressions like ternaries\n  and `Array.map`.\n- Objects as children: `{myObject}` will throw; use `JSON.stringify` or\n  extract individual properties.\n\n**Rule of thumb:** if it can go on the right-hand side of `=`, it can go\ninside `{}`.\n",{"id":57,"difficulty":58,"q":59,"a":60},"jsx-vs-html-differences","medium","What are the key differences between JSX and HTML?","Several attribute names and rules differ:\n\n| HTML | JSX | Reason |\n|------|-----|--------|\n| `class` | `className` | `class` is a reserved JS keyword |\n| `for` | `htmlFor` | `for` is a reserved JS keyword |\n| `onclick` | `onClick` | Events use camelCase in JSX |\n| `\u003Cbr>` | `\u003Cbr \u002F>` | All tags must be closed in JSX |\n| `style=\"color:red\"` | `style={{ color: 'red' }}` | Style takes a JS object |\n| `tabindex` | `tabIndex` | camelCase for multi-word attributes |\n\n```jsx\n\u002F\u002F HTML\n\u002F\u002F \u003Clabel class=\"label\" for=\"email\" onclick=\"submit()\">Email\u003C\u002Flabel>\n\n\u002F\u002F JSX\n\u003Clabel className=\"label\" htmlFor=\"email\" onClick={submit}>Email\u003C\u002Flabel>\n```\n\nAdditionally, JSX is case-sensitive: `\u003Cdiv>` is a DOM element; `\u003CDiv>`\nwould be treated as a custom component.\n\n**Rule of thumb:** when an HTML attribute doesn't work in JSX, check if\nit's a reserved keyword or needs camelCase.\n",{"id":62,"difficulty":58,"q":63,"a":64},"boolean-attributes","How does JSX handle boolean attributes?","In JSX, omitting a value for an attribute is the same as setting it to\n`true`. You never write `disabled=\"true\"` — that's an HTML string, not a\nboolean.\n\n```jsx\n\u002F\u002F These are equivalent\n\u003Cinput disabled={true} \u002F>\n\u003Cinput disabled \u002F>\n\n\u002F\u002F Explicitly false — attribute is omitted from the DOM\n\u003Cinput disabled={false} \u002F>\n\n\u002F\u002F Dynamic\n\u003Cbutton disabled={isLoading}>Submit\u003C\u002Fbutton>\n```\n\nA common mistake is `disabled=\"false\"` — HTML treats any non-empty string\nas truthy, so the button would still be disabled. Always use `{false}`.\n\n**Rule of thumb:** use `{true}` \u002F `{false}` for any attribute that has a\nboolean semantic; never pass boolean values as strings.\n",{"id":66,"difficulty":58,"q":67,"a":68},"uppercase-component-names","Why must custom component names start with an uppercase letter in JSX?","JSX uses the case of the first letter to decide how to compile the tag:\n\n- **Lowercase** (`\u003Cdiv>`, `\u003Cspan>`) → `React.createElement('div', …)` —\n  passed as a **string**, rendered as a native DOM element.\n- **Uppercase** (`\u003CMyComponent>`) → `React.createElement(MyComponent, …)` —\n  passed as a **variable reference**, rendered as a React component.\n\n```jsx\n\u002F\u002F React treats 'button' as a DOM element — works as expected\nconst el = \u003Cbutton onClick={handle}>Click\u003C\u002Fbutton>\n\n\u002F\u002F React looks up `button` as a variable — ReferenceError if not defined\nconst el = \u003Cbutton \u002F>   \u002F\u002F ← lowercase: treated as DOM tag, fine\nconst el = \u003CButton \u002F>   \u002F\u002F ← uppercase: looks for a `Button` variable\n```\n\nIf you store a component in a lowercase variable, you must reassign it to\nan uppercase one before using it in JSX:\n\n```jsx\nconst components = { circle: CircleIcon }\nconst Icon = components['circle']   \u002F\u002F uppercase alias required\nreturn \u003CIcon \u002F>\n```\n\n**Rule of thumb:** always capitalize component names; use lowercase only\nfor HTML intrinsic elements.\n",{"id":70,"difficulty":33,"q":71,"a":72},"style-in-jsx","How do you apply inline styles in JSX?","The `style` prop takes a **JavaScript object**, not a CSS string. Property\nnames are camelCase versions of their CSS counterparts.\n\n```jsx\n\u002F\u002F ❌ HTML-style string — not valid in JSX\n\u003Cdiv style=\"color: red; font-size: 16px\">…\u003C\u002Fdiv>\n\n\u002F\u002F ✅ JSX object — note the double braces: outer {} for expression,\n\u002F\u002F    inner {} for the object literal\n\u003Cdiv style={{ color: 'red', fontSize: '16px', marginTop: 8 }}>…\u003C\u002Fdiv>\n```\n\nValues that are numbers (like `marginTop: 8`) are automatically converted\nto pixels for properties that accept pixel units. Values for others (like\n`opacity: 0.5`) are used as-is.\n\n**Rule of thumb:** for anything beyond a quick prototype, prefer CSS\nmodules or a utility class over inline styles — they don't support media\nqueries or pseudo-selectors.\n",{"id":74,"difficulty":33,"q":75,"a":76},"jsx-comments","How do you write comments in JSX?","Comments inside JSX must be wrapped in `{}` and use the `\u002F* … *\u002F` syntax —\nnot `\u002F\u002F`, which would comment out the closing `}` as well.\n\n```jsx\nreturn (\n  \u003Cdiv>\n    {\u002F* This is a JSX comment — it won't appear in the rendered output *\u002F}\n    \u003Cp>Visible text\u003C\u002Fp>\n    {\u002F* \u003Cp>Commented-out element\u003C\u002Fp> *\u002F}\n  \u003C\u002Fdiv>\n)\n```\n\nOutside of JSX (above the `return`), normal JS comments work fine.\n\n**Rule of thumb:** `{\u002F* comment *\u002F}` inside JSX, `\u002F\u002F comment` outside.\n",{"id":78,"difficulty":58,"q":79,"a":80},"jsx-spread-attributes","How do you spread an object's properties onto a JSX element?","Use the spread syntax `{...obj}` to forward a set of props without listing\neach one individually.\n\n```jsx\nconst buttonProps = { type: 'button', disabled: false, 'aria-label': 'Save' }\nreturn \u003Cbutton {...buttonProps}>Save\u003C\u002Fbutton>\n\n\u002F\u002F Equivalent to:\nreturn \u003Cbutton type=\"button\" disabled={false} aria-label=\"Save\">Save\u003C\u002Fbutton>\n```\n\nA common pattern in wrapper components:\n\n```jsx\nfunction IconButton({ icon, children, ...rest }) {\n  \u002F\u002F `rest` captures all props not explicitly destructured\n  return (\n    \u003Cbutton {...rest}>\n      \u003CIcon name={icon} \u002F>\n      {children}\n    \u003C\u002Fbutton>\n  )\n}\n```\n\n**Rule of thumb:** spread props enable flexible pass-through but make it\neasy to accidentally forward unknown props to DOM elements (which triggers\nReact warnings). Destructure known props and spread only the remainder.\n",{"id":82,"difficulty":33,"q":83,"a":84},"rendering-null","What happens when a component returns null?","Returning `null` renders **nothing** — the component mounts (lifecycle runs,\nrefs attach) but contributes no DOM nodes. It's the idiomatic way to\nconditionally hide output without unmounting.\n\n```jsx\nfunction Banner({ show, message }) {\n  if (!show) return null\n  return \u003Cdiv className=\"banner\">{message}\u003C\u002Fdiv>\n}\n```\n\nCrucially, returning `null` is different from not rendering the component\nat all:\n- `null` → component mounts; `useEffect` and refs still fire.\n- Conditional rendering (`{show && \u003CBanner \u002F>}`) → component is not mounted\n  when `show` is false; effects and state are destroyed.\n\n**Rule of thumb:** return `null` when you want the component in the tree\n(for effects or imperative refs) but invisible; use conditional rendering\nwhen you want it fully gone.\n",{"id":86,"difficulty":58,"q":87,"a":88},"rendering-arrays","How do you render an array of elements in JSX?","React can render an array of React elements as a child. The standard\napproach is `Array.map`:\n\n```jsx\nconst fruits = ['Apple', 'Banana', 'Cherry']\n\nreturn (\n  \u003Cul>\n    {fruits.map(fruit => (\n      \u003Cli key={fruit}>{fruit}\u003C\u002Fli>   \u002F\u002F key is required on the outermost element\n    ))}\n  \u003C\u002Ful>\n)\n```\n\nReact also accepts arrays returned directly:\n\n```jsx\nfunction Tags({ tags }) {\n  return tags.map(tag => \u003Cspan key={tag} className=\"tag\">{tag}\u003C\u002Fspan>)\n}\n```\n\nThings that React will **not** render as children: plain objects, `undefined`\n(silently skipped), and `false` (silently skipped — useful for short-circuits).\n\n**Rule of thumb:** always add a stable `key` to each element in a mapped\nlist; without it, React warns and may produce incorrect diffs.\n",{"id":90,"difficulty":58,"q":91,"a":92},"double-braces","What is the difference between single {} and double {{}} in JSX?","Single `{}` opens a JavaScript **expression slot** in JSX. Double `{{}}`\nis simply that expression slot containing an **object literal** — there's\nno special double-brace syntax.\n\n```jsx\n\u002F\u002F {} — expression slot\n\u003Cp>{count}\u003C\u002Fp>\n\n\u002F\u002F {{}} — expression slot containing an object literal\n\u003Cdiv style={{ color: 'red', fontSize: 16 }}>…\u003C\u002Fdiv>\n\u002F\u002F          ^outer: JSX expression  ^inner: JS object\n```\n\nThe confusion usually arises with `style` because it's the most common\nattribute that takes an object value.\n\n**Rule of thumb:** think of it as two separate things: \"open expression\"\nthen \"open object\". The outer `{}` is JSX; the inner `{}` is JavaScript.\n",{"id":94,"difficulty":33,"q":95,"a":96},"self-closing-tags","When must a JSX tag be self-closing?","In JSX, every element **must** be explicitly closed — either with a closing\ntag or with `\u002F>` for self-closing. This is stricter than HTML, where void\nelements like `\u003Cbr>` and `\u003Cimg>` don't require closing.\n\n```jsx\n\u002F\u002F ❌ HTML-style void element — invalid in JSX\n\u003Cinput type=\"text\">\n\u003Cimg src=\"photo.jpg\">\n\n\u002F\u002F ✅ Self-close when there are no children\n\u003Cinput type=\"text\" \u002F>\n\u003Cimg src=\"photo.jpg\" \u002F>\n\n\u002F\u002F ✅ Or use a closing tag (unusual for void elements, but valid JSX)\n\u003Cinput type=\"text\">\u003C\u002Finput>\n```\n\nCustom components can also be self-closed when you pass no children:\n`\u003CMyWidget \u002F>`.\n\n**Rule of thumb:** if an element has no children, self-close it with `\u002F>`;\nnever leave a tag unclosed in JSX.\n",{"id":98,"difficulty":58,"q":99,"a":100},"jsx-children-prop","How is the children prop passed and accessed in JSX?","Anything placed **between** opening and closing JSX tags is automatically\npassed as the `children` prop.\n\n```jsx\nfunction Card({ title, children }) {\n  return (\n    \u003Cdiv className=\"card\">\n      \u003Ch2>{title}\u003C\u002Fh2>\n      \u003Cdiv className=\"body\">{children}\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F Usage — the \u003Cp> and \u003Cbutton> become children\n\u003CCard title=\"Welcome\">\n  \u003Cp>Hello there!\u003C\u002Fp>\n  \u003Cbutton>OK\u003C\u002Fbutton>\n\u003C\u002FCard>\n```\n\n`children` can be a string, a single element, an array of elements, or\neven a function (render prop pattern). Use `React.Children` utilities if\nyou need to iterate or count children programmatically.\n\n**Rule of thumb:** `children` is just a prop; you can also pass it\nexplicitly as `\u003CCard children={\u003Cp>Hi\u003C\u002Fp>} \u002F>`, though the nested form is\nmore readable.\n",{"id":102,"difficulty":58,"q":103,"a":104},"conditional-in-jsx","Can you use an if statement directly inside JSX? What should you do instead?","No — `if` is a statement, not an expression, so it can't go inside `{}`.\nJSX only accepts expressions.\n\n```jsx\n\u002F\u002F ❌ if statement inside JSX — syntax error\nreturn (\n  \u003Cdiv>\n    {if (isLoggedIn) { return \u003CDashboard \u002F> }}\n  \u003C\u002Fdiv>\n)\n\n\u002F\u002F ✅ Ternary — an expression\nreturn (\n  \u003Cdiv>\n    {isLoggedIn ? \u003CDashboard \u002F> : \u003CLogin \u002F>}\n  \u003C\u002Fdiv>\n)\n\n\u002F\u002F ✅ Logical && — renders right side only if left is truthy\nreturn (\n  \u003Cdiv>\n    {isAdmin && \u003CAdminPanel \u002F>}\n  \u003C\u002Fdiv>\n)\n\n\u002F\u002F ✅ If\u002Felse above the return — perfectly fine\nlet content\nif (isLoggedIn) { content = \u003CDashboard \u002F> }\nelse { content = \u003CLogin \u002F> }\nreturn \u003Cdiv>{content}\u003C\u002Fdiv>\n```\n\n**Rule of thumb:** for simple two-path branches use a ternary; for one-side\nrendering use `&&`; for complex logic extract it above the `return`.\n",16,null,{"description":31},"React JSX interview questions — JSX syntax, transpilation, fragments, expressions, boolean attributes, and the differences between JSX and HTML.","react\u002Fcomponents\u002Fjsx-rendering","JSX and Rendering","2026-06-23","yl8pAZz6eXYk_NZkXSaQAtjCi9t1s27W0dWeiEbz0pk",{"id":114,"title":115,"body":116,"description":31,"difficulty":33,"extension":34,"framework":10,"frameworkSlug":8,"meta":120,"navigation":37,"order":11,"path":122,"questions":123,"questionsCount":105,"related":106,"seo":189,"seoDescription":190,"stem":191,"subtopic":192,"topic":19,"topicSlug":20,"updated":111,"__hash__":193},"qa\u002Freact\u002Fcomponents\u002Fprops-component-types.md","Props Component Types",{"type":28,"value":117,"toc":118},[],{"title":31,"searchDepth":11,"depth":11,"links":119},[],{"subtopicSlug":121},"props-component-types","\u002Freact\u002Fcomponents\u002Fprops-component-types",[124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184],{"id":125,"difficulty":33,"q":126,"a":127},"what-are-props","What are props in React?","**Props** (short for properties) are the mechanism React uses to pass data\n**down** from a parent component to a child. They are received by the child\nas a plain JavaScript object and are **read-only** — a component must never\nmodify its own props.\n\n```jsx\n\u002F\u002F Parent passes props\n\u003CGreeting name=\"Alice\" age={30} isAdmin \u002F>\n\n\u002F\u002F Child receives them\nfunction Greeting({ name, age, isAdmin }) {\n  return \u003Cp>{name} ({age}) — {isAdmin ? 'Admin' : 'User'}\u003C\u002Fp>\n}\n```\n\nProps can be any JavaScript value: strings, numbers, booleans, objects,\narrays, or even functions and React elements. Whatever you put between\nopening and closing tags flows in as `children`.\n\n**Rule of thumb:** props flow down, never up. If a child needs to\ncommunicate to its parent, pass a callback function as a prop.\n",{"id":129,"difficulty":33,"q":130,"a":131},"props-immutable","Are props mutable inside a component? Why not?","No. Props are **read-only** in React by design. A component is a pure\nfunction of its props (and state): given the same inputs it should always\nproduce the same output.\n\n```jsx\nfunction Badge({ count }) {\n  \u002F\u002F ❌ Never do this\n  count = count + 1\n\n  \u002F\u002F ✅ Derive a new value without mutating\n  const displayCount = count > 99 ? '99+' : count\n  return \u003Cspan>{displayCount}\u003C\u002Fspan>\n}\n```\n\nIf you try to reassign a prop it may work locally (it's just a JS variable),\nbut the change won't persist across renders and will confuse React's\nreconciler because the parent still owns the original value.\n\n**Rule of thumb:** treat every prop as a `const`. To derive a modified\nvalue, create a new local variable; to change what the parent passes, fire\na callback that updates the parent's state.\n",{"id":133,"difficulty":33,"q":134,"a":135},"children-prop","What is the children prop?","`children` is the implicit prop that React populates with whatever you put\n**between** a component's JSX tags. It enables composition — parent decides\nthe shell, child slot receives arbitrary content.\n\n```jsx\nfunction Panel({ title, children }) {\n  return (\n    \u003Csection className=\"panel\">\n      \u003Ch2>{title}\u003C\u002Fh2>\n      \u003Cdiv className=\"panel-body\">{children}\u003C\u002Fdiv>\n    \u003C\u002Fsection>\n  )\n}\n\n\u002F\u002F Usage\n\u003CPanel title=\"Stats\">\n  \u003Cp>Revenue: $1,200\u003C\u002Fp>\n  \u003CChart data={data} \u002F>\n\u003C\u002FPanel>\n```\n\n`children` can be a string, a single element, an array of elements, a\nfunction (render prop), or `undefined` (nothing passed). Use\n`React.Children.count(children)` or `React.Children.toArray(children)` to\ninspect it programmatically.\n\n**Rule of thumb:** `children` is just a prop with special JSX sugar. It\nlets you build generic \"container\" components that don't need to know what\ngoes inside them.\n",{"id":137,"difficulty":58,"q":138,"a":139},"function-vs-class","What is the difference between a function component and a class component?","| | Function component | Class component |\n|---|---|---|\n| Syntax | Plain JS function | `class X extends React.Component` |\n| State | `useState`, `useReducer` | `this.state` \u002F `this.setState` |\n| Lifecycle | `useEffect` | `componentDidMount`, `componentDidUpdate`, etc. |\n| Context | `useContext` | `static contextType` \u002F `Context.Consumer` |\n| `this` | Not applicable | Required for everything |\n| Error boundaries | Not supported | `componentDidCatch` |\n\n```jsx\n\u002F\u002F Function component\nfunction Counter() {\n  const [n, setN] = useState(0)\n  return \u003Cbutton onClick={() => setN(n + 1)}>{n}\u003C\u002Fbutton>\n}\n\n\u002F\u002F Class component — equivalent\nclass Counter extends React.Component {\n  state = { n: 0 }\n  render() {\n    return \u003Cbutton onClick={() => this.setState({ n: this.state.n + 1 })}>{this.state.n}\u003C\u002Fbutton>\n  }\n}\n```\n\nSince React 16.8 (hooks), function components can do everything class\ncomponents can except implement error boundaries. New code should use\nfunction components.\n\n**Rule of thumb:** always write function components. Only reach for a class\nwhen you need a `componentDidCatch` error boundary — or when you're\nmaintaining legacy code.\n",{"id":141,"difficulty":58,"q":142,"a":143},"when-class-component","Is there any reason to use a class component in modern React?","The only built-in feature class components have that function components\nlack is the ability to serve as an **error boundary** via\n`componentDidCatch` and `getDerivedStateFromError`. There is no hooks-based\nequivalent in React itself (as of 2024).\n\n```jsx\nclass ErrorBoundary extends React.Component {\n  state = { hasError: false }\n\n  static getDerivedStateFromError() {\n    return { hasError: true }\n  }\n\n  componentDidCatch(err, info) {\n    logError(err, info)\n  }\n\n  render() {\n    return this.state.hasError\n      ? \u003Cp>Something went wrong.\u003C\u002Fp>\n      : this.props.children\n  }\n}\n```\n\nIn practice most teams write a single `ErrorBoundary` class component and\nreach for third-party wrappers like `react-error-boundary` everywhere else.\n\n**Rule of thumb:** one class component per project (the error boundary).\nEverything else is a function component.\n",{"id":145,"difficulty":33,"q":146,"a":147},"default-props","How do you provide default values for props?","The modern idiomatic approach is **default parameter destructuring**:\n\n```jsx\nfunction Button({ label = 'Click me', variant = 'primary', disabled = false }) {\n  return \u003Cbutton className={variant} disabled={disabled}>{label}\u003C\u002Fbutton>\n}\n```\n\nAlternatively, you can use the `defaultProps` static property, but this is\nconsidered legacy and may be removed in a future major version:\n\n```jsx\nButton.defaultProps = {\n  label: 'Click me',\n  variant: 'primary',\n  disabled: false,\n}\n```\n\nFor TypeScript users, the destructuring approach integrates cleanly with\ntype annotations:\n\n```tsx\ntype ButtonProps = { label?: string; variant?: 'primary' | 'secondary' }\nfunction Button({ label = 'Click me', variant = 'primary' }: ButtonProps) { … }\n```\n\n**Rule of thumb:** use destructuring defaults; they're co-located with the\nparameter list and work without any React-specific API.\n",{"id":149,"difficulty":58,"q":150,"a":151},"proptypes","What is PropTypes and when would you use it?","`PropTypes` is a runtime prop validation library that ships separately\n(`prop-types` package). In development mode it logs warnings when props\nfail the declared type, catching mistakes early.\n\n```jsx\nimport PropTypes from 'prop-types'\n\nfunction Avatar({ name, size, src }) {\n  return \u003Cimg src={src} alt={name} width={size} \u002F>\n}\n\nAvatar.propTypes = {\n  name: PropTypes.string.isRequired,\n  size: PropTypes.number,\n  src: PropTypes.string.isRequired,\n}\n\nAvatar.defaultProps = { size: 48 }\n```\n\nPropTypes are stripped in production builds. The trade-off vs TypeScript:\n- **PropTypes** — runtime, no build-step, catches type mistakes at render\n  time in any JS project.\n- **TypeScript** — compile-time, catches mistakes before runtime, broader\n  coverage (not just props).\n\n**Rule of thumb:** in a TypeScript project, TypeScript alone is sufficient.\nIn a plain JS project, PropTypes are a lightweight safety net.\n",{"id":153,"difficulty":33,"q":154,"a":155},"props-vs-state","What is the difference between props and state?","| | Props | State |\n|---|---|---|\n| Owned by | Parent component | Component itself |\n| Mutable by | Parent only | The component (`setState` \u002F setter) |\n| Triggers re-render | When parent re-renders | When updated via setter |\n| Purpose | Pass data in | Track internal data that changes |\n\n```jsx\nfunction Thermometer({ unit }) {       \u002F\u002F unit is a prop — parent decides\n  const [temp, setTemp] = useState(20) \u002F\u002F temp is state — component owns it\n  return (\n    \u003Cdiv>\n      {temp}° {unit}\n      \u003Cbutton onClick={() => setTemp(t => t + 1)}>+\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  )\n}\n```\n\nA useful mental model: props are like function arguments; state is like\nlocal variables that persist between calls.\n\n**Rule of thumb:** if a value is determined by the outside world, it's a\nprop. If it's determined by the component itself and can change, it's state.\n",{"id":157,"difficulty":58,"q":158,"a":159},"prop-drilling","What is prop drilling and what are the alternatives?","**Prop drilling** occurs when a prop must be passed through several\nintermediate layers that don't use it — just to get it to a deeply nested\ncomponent.\n\n```jsx\n\u002F\u002F Drilling `user` through three layers that don't care about it\n\u003CApp user={user}>\n  \u003CLayout user={user}>\n    \u003CSidebar user={user}>\n      \u003CAvatar user={user} \u002F>   {\u002F* ← only Avatar actually uses it *\u002F}\n    \u003C\u002FSidebar>\n  \u003C\u002FLayout>\n\u003C\u002FApp>\n```\n\nAlternatives:\n1. **Context API** — `React.createContext` + `useContext`. Best for\n   genuinely global or cross-cutting data (theme, current user, locale).\n2. **Component composition \u002F children** — pass `\u003CAvatar user={user} \u002F>`\n   as a child instead of passing `user` through intermediaries.\n3. **State management library** — Zustand, Redux, Jotai — good when many\n   unrelated components need the same data.\n\n**Rule of thumb:** before reaching for Context, try restructuring with\ncomposition. Context adds implicit coupling; explicit props are easier to\ntrace.\n",{"id":161,"difficulty":33,"q":162,"a":163},"destructuring-props","How do you destructure props and why is it preferred?","Destructure props directly in the function signature rather than accessing\nthem via the `props` object — it's more concise and makes required fields\nobvious.\n\n```jsx\n\u002F\u002F Verbose\nfunction Card(props) {\n  return \u003Cdiv className={props.variant}>{props.children}\u003C\u002Fdiv>\n}\n\n\u002F\u002F Destructured — preferred\nfunction Card({ variant, children }) {\n  return \u003Cdiv className={variant}>{children}\u003C\u002Fdiv>\n}\n\n\u002F\u002F With defaults and rest\nfunction Card({ variant = 'default', className = '', children, ...rest }) {\n  return (\n    \u003Cdiv className={`card card-${variant} ${className}`} {...rest}>\n      {children}\n    \u003C\u002Fdiv>\n  )\n}\n```\n\n**Rule of thumb:** destructure all props at the function signature. For\nlarge prop objects, consider grouping related props into sub-objects\n(`position={{ x, y }}`) to keep the signature readable.\n",{"id":165,"difficulty":33,"q":166,"a":167},"handler-as-prop","How do you pass an event handler as a prop?","Pass the function **reference** as a prop, not the function call. The child\nreceives it and calls it when the event fires.\n\n```jsx\n\u002F\u002F Parent\nfunction Form() {\n  function handleSubmit(data) {\n    console.log(data)\n  }\n  return \u003CSubmitButton onSubmit={handleSubmit} label=\"Save\" \u002F>\n}\n\n\u002F\u002F Child — receives and calls the handler\nfunction SubmitButton({ onSubmit, label }) {\n  return \u003Cbutton onClick={() => onSubmit({ time: Date.now() })}>{label}\u003C\u002Fbutton>\n}\n```\n\nConvention: name callback props with the `on` prefix (`onChange`, `onClose`,\n`onSubmit`) to signal that they are event-like.\n\n**Rule of thumb:** pass function references, not calls. `onClick={handle}`\npasses the function; `onClick={handle()}` calls it immediately and passes\nits return value — almost never what you want.\n",{"id":169,"difficulty":58,"q":170,"a":171},"spread-props","What is the spread-props pattern and when should you use it?","Spread props (`{...rest}`) forward a batch of unknown props to a child\nwithout enumerating each one. It's most useful in wrapper\u002Fadapter\ncomponents.\n\n```jsx\nfunction Input({ label, error, ...inputProps }) {\n  \u002F\u002F label and error are consumed here; everything else goes to \u003Cinput>\n  return (\n    \u003Cdiv>\n      \u003Clabel>{label}\u003C\u002Flabel>\n      \u003Cinput {...inputProps} \u002F>\n      {error && \u003Cspan className=\"error\">{error}\u003C\u002Fspan>}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F Usage — all native \u003Cinput> attributes work without any boilerplate\n\u003CInput label=\"Email\" type=\"email\" name=\"email\" required error={errors.email} \u002F>\n```\n\n**Caution:** spreading onto DOM elements can forward non-standard props,\nwhich React will warn about. Always destructure known props first and spread\nthe remainder.\n\n**Rule of thumb:** spread `...rest` to DOM wrappers; avoid spreading the\nfull props object without filtering — it leaks internal props.\n",{"id":173,"difficulty":58,"q":174,"a":175},"pure-component","What is a pure component in React?","A **pure component** is one whose output depends only on its props (and\nstate), with no side effects during rendering. Given the same inputs it\nalways returns the same JSX — like a pure function in FP.\n\nIn class components, `React.PureComponent` adds a shallow-equality check\nin `shouldComponentUpdate`, preventing re-renders when props haven't\nchanged.\n\nIn function components, `React.memo` provides the same shallow-equality\nbail-out:\n\n```jsx\n\u002F\u002F Without memo — re-renders every time parent re-renders\nfunction Label({ text }) {\n  return \u003Cspan>{text}\u003C\u002Fspan>\n}\n\n\u002F\u002F With memo — skips re-render if text hasn't changed\nconst Label = React.memo(function Label({ text }) {\n  return \u003Cspan>{text}\u003C\u002Fspan>\n})\n```\n\n**Rule of thumb:** apply `React.memo` only to components that render\nfrequently with the same props and are measurably expensive. Premature\nmemoization adds complexity without benefit — profile first.\n",{"id":177,"difficulty":58,"q":178,"a":179},"composition-vs-inheritance","Why does React prefer composition over inheritance?","React's component model is built around **composition**: assembling behavior\nby combining components, not by extending them. The React team explicitly\nrecommends against using inheritance between components (other than extending\n`React.Component` once).\n\nComposition approaches:\n- **Children prop** — slot any content into a component.\n- **Specialized components** — make a `\u003CDialog>` and then a `\u003CAlertDialog>`\n  that renders a pre-configured `\u003CDialog>`, not one that extends it.\n- **Render props \u002F HOCs** — share logic without shared class hierarchies.\n\n```jsx\n\u002F\u002F ✅ Composition\nfunction SuccessDialog({ children }) {\n  return \u003CDialog icon=\"check\" title=\"Success\">{children}\u003C\u002FDialog>\n}\n\n\u002F\u002F ❌ Inheritance — unusual in React, actively discouraged\nclass SuccessDialog extends Dialog { … }\n```\n\n**Rule of thumb:** when you think \"I want a component like X but with Y\nchanged,\" reach for composition (wrap, extend via props, or use children)\nbefore ever reaching for class inheritance.\n",{"id":181,"difficulty":58,"q":182,"a":183},"controlled-component","What is a controlled component?","A **controlled component** is a form element whose value is **driven by\nReact state** rather than by the DOM. React is the single source of truth.\n\n```jsx\nfunction LoginForm() {\n  const [email, setEmail] = useState('')\n\n  return (\n    \u003Cinput\n      type=\"email\"\n      value={email}          \u002F\u002F state drives the displayed value\n      onChange={e => setEmail(e.target.value)}   \u002F\u002F state updated on change\n    \u002F>\n  )\n}\n```\n\nEvery keystroke calls `setEmail`, which updates state, which re-renders,\nwhich sets `value` — a tight loop. This means you can validate, transform,\nor intercept input on every change.\n\nThe alternative, **uncontrolled components**, read values from the DOM via\na ref at submission time rather than tracking each change.\n\n**Rule of thumb:** use controlled inputs when you need real-time validation\nor to format input as the user types; uncontrolled when the form is simple\nand you only need values on submit.\n",{"id":185,"difficulty":186,"q":187,"a":188},"render-props","hard","What is the render-props pattern?","A **render prop** is a prop whose value is a function, allowing one\ncomponent to delegate rendering decisions to its parent. It's a technique\nfor sharing stateful logic without hooks or HOCs.\n\n```jsx\n\u002F\u002F Provider of the logic\nfunction MouseTracker({ render }) {\n  const [pos, setPos] = useState({ x: 0, y: 0 })\n  return (\n    \u003Cdiv onMouseMove={e => setPos({ x: e.clientX, y: e.clientY })}>\n      {render(pos)}   {\u002F* call the function to get JSX *\u002F}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F Consumer decides what to display\n\u003CMouseTracker render={({ x, y }) => (\n  \u003Cp>Mouse at {x}, {y}\u003C\u002Fp>\n)} \u002F>\n```\n\nThe `children` prop can be used the same way (and often is):\n\n```jsx\n\u003CMouseTracker>\n  {({ x, y }) => \u003Cp>Mouse at {x}, {y}\u003C\u002Fp>}\n\u003C\u002FMouseTracker>\n```\n\nIn modern code, custom hooks replace most render-prop use cases with less\nindirection.\n\n**Rule of thumb:** know the pattern for interviews; in practice, custom\nhooks are almost always cleaner.\n",{"description":31},"React props and component types interview questions — function vs class components, children, defaultProps, PropTypes, composition over inheritance, and controlled components.","react\u002Fcomponents\u002Fprops-component-types","Props and Component Types","JOU2b0dj3z8YqBLCQ001LOO430R9KMVhifMegiHzHE8",{"id":195,"title":196,"body":197,"description":31,"difficulty":33,"extension":34,"framework":10,"frameworkSlug":8,"meta":201,"navigation":37,"order":203,"path":204,"questions":205,"questionsCount":274,"related":106,"seo":275,"seoDescription":276,"stem":277,"subtopic":196,"topic":19,"topicSlug":20,"updated":111,"__hash__":278},"qa\u002Freact\u002Fcomponents\u002Fevent-handling.md","Event Handling",{"type":28,"value":198,"toc":199},[],{"title":31,"searchDepth":11,"depth":11,"links":200},[],{"subtopicSlug":202},"event-handling",3,"\u002Freact\u002Fcomponents\u002Fevent-handling",[206,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,270],{"id":207,"difficulty":33,"q":208,"a":209},"attach-event-handler","How do you attach an event handler to an element in React?","Pass a **function reference** as a camelCase prop on the JSX element.\nReact registers the handler for you via its internal event system.\n\n```jsx\nfunction ClickCounter() {\n  const [count, setCount] = useState(0)\n\n  function handleClick() {\n    setCount(c => c + 1)\n  }\n\n  return \u003Cbutton onClick={handleClick}>Clicked {count} times\u003C\u002Fbutton>\n}\n```\n\nCommon pitfalls:\n- `onClick={handleClick()}` — calls the function immediately during render\n  and passes its return value. Correct form omits the `()`.\n- Arrow functions inline are fine but create a new function each render,\n  which can matter for memoized children.\n\n**Rule of thumb:** name handlers `handleEventName` by convention; pass\nthem as `onEventName={handler}` — no parentheses.\n",{"id":211,"difficulty":58,"q":212,"a":213},"synthetic-event","What is a SyntheticEvent in React?","React wraps native browser events in a **SyntheticEvent** — a cross-browser\nwrapper that normalizes differences in the native event API (e.g. IE vs\nChrome). It exposes the same interface as the native event\n(`target`, `preventDefault()`, `stopPropagation()`, etc.) but works\nconsistently everywhere.\n\n```jsx\nfunction Input() {\n  function handleChange(e) {\n    \u002F\u002F e is a SyntheticEvent\n    console.log(e.target.value)   \u002F\u002F same API as native InputEvent\n    console.log(e.nativeEvent)    \u002F\u002F access the raw browser event\n  }\n  return \u003Cinput onChange={handleChange} \u002F>\n}\n```\n\n**React 17 change:** prior to React 17, synthetic events were **pooled**\n(reused after the handler returned, with all properties set to `null`). In\nReact 17+, pooling was removed — you can safely access the event\nasynchronously.\n\n**Rule of thumb:** treat a SyntheticEvent exactly like a native DOM event.\nIf you need the raw event, it's on `e.nativeEvent`.\n",{"id":215,"difficulty":33,"q":216,"a":217},"camelcase-events","Why do React event names use camelCase?","Because JSX is JavaScript, not HTML. In HTML, event attributes are lowercase\nstrings (`onclick`, `onmouseover`). In JSX, they are **JavaScript property\nnames** on the props object, and the React team chose camelCase as the\nconvention to match JavaScript idioms.\n\n```jsx\n\u002F\u002F HTML\n\u002F\u002F \u003Cbutton onclick=\"handler()\">\n\n\u002F\u002F JSX\n\u003Cbutton onClick={handler}>\n\n\u002F\u002F More examples\n\u003Cinput onChange={handle} onFocus={handle} onBlur={handle} \u002F>\n\u003Cform onSubmit={handle} \u002F>\n\u003Cdiv onMouseEnter={handle} onMouseLeave={handle} \u002F>\n```\n\n**Rule of thumb:** every DOM event is available in React as `on` +\nPascalCase (e.g. `click` → `onClick`, `keydown` → `onKeyDown`).\n",{"id":219,"difficulty":33,"q":220,"a":221},"prevent-default","How do you prevent default browser behavior in React?","Call `e.preventDefault()` on the SyntheticEvent inside your handler.\n\n```jsx\nfunction LoginForm() {\n  function handleSubmit(e) {\n    e.preventDefault()          \u002F\u002F stops the full-page form POST\n    \u002F\u002F ... handle submission with fetch\n  }\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput name=\"email\" type=\"email\" \u002F>\n      \u003Cbutton type=\"submit\">Log in\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n```\n\nCommon use cases:\n- `\u003Cform>` `onSubmit` — prevent page reload.\n- `\u003Ca>` `onClick` — prevent navigation to `href`.\n- Drag events — prevent the default drop behavior.\n\n**Rule of thumb:** call `preventDefault()` at the top of your handler\nbefore any async work — after an `await`, the event may have already\nbeen handled by the browser.\n",{"id":223,"difficulty":58,"q":224,"a":225},"return-false","Why can't you return false to prevent default behavior in React?","In plain HTML event attributes (`onclick=\"return false\"`), returning `false`\nwas a shortcut that both prevented the default and stopped propagation.\nReact **does not** support this shortcut.\n\nReact event handlers are regular JavaScript functions — returning `false`\nfrom them has no special meaning to React's event system.\n\n```jsx\n\u002F\u002F ❌ Doesn't work in React — return value is ignored\n\u003Ca href=\"\u002Fhome\" onClick={() => false}>Go\u003C\u002Fa>\n\n\u002F\u002F ✅ Explicit calls are required\n\u003Ca\n  href=\"\u002Fhome\"\n  onClick={e => {\n    e.preventDefault()\n    e.stopPropagation()\n  }}\n>\n  Go\n\u003C\u002Fa>\n```\n\n**Rule of thumb:** always call `e.preventDefault()` and\u002For\n`e.stopPropagation()` explicitly; never rely on return values.\n",{"id":227,"difficulty":58,"q":228,"a":229},"stop-propagation","What is the difference between stopPropagation and preventDefault?","They control two completely different things:\n\n- **`e.preventDefault()`** — stops the browser from running its built-in\n  action for the event (e.g. form submission, link navigation, checkbox\n  toggle). The event still bubbles up through the DOM.\n\n- **`e.stopPropagation()`** — stops the event from bubbling further up the\n  DOM tree. Parent handlers won't fire. Does not affect the browser action.\n\n```jsx\nfunction List() {\n  return (\n    \u003Cul onClick={() => console.log('list clicked')}>\n      \u003Cli>\n        \u003Ca\n          href=\"\u002Fdetail\"\n          onClick={e => {\n            e.preventDefault()    \u002F\u002F don't navigate to \u002Fdetail\n            e.stopPropagation()   \u002F\u002F don't trigger the ul's onClick\n            navigate('\u002Fmodal')\n          }}\n        >\n          View\n        \u003C\u002Fa>\n      \u003C\u002Fli>\n    \u003C\u002Ful>\n  )\n}\n```\n\n**Rule of thumb:** call `preventDefault` to suppress browser behavior;\ncall `stopPropagation` to prevent parent handlers from also running.\nYou often need both for nested interactive elements.\n",{"id":231,"difficulty":58,"q":232,"a":233},"passing-arguments","How do you pass arguments to an event handler?","Wrap the handler in an arrow function or use `.bind`. The arrow-function\napproach is more common in JSX.\n\n```jsx\nfunction ItemList({ items }) {\n  function handleDelete(id, e) {\n    e.stopPropagation()\n    deleteItem(id)\n  }\n\n  return (\n    \u003Cul>\n      {items.map(item => (\n        \u003Cli key={item.id}>\n          {item.name}\n          {\u002F* Arrow wrapper — creates a new fn per render *\u002F}\n          \u003Cbutton onClick={e => handleDelete(item.id, e)}>Delete\u003C\u002Fbutton>\n        \u003C\u002Fli>\n      ))}\n    \u003C\u002Ful>\n  )\n}\n```\n\nFor performance-sensitive lists, you can use data attributes instead:\n\n```jsx\nfunction handleDelete(e) {\n  const id = e.currentTarget.dataset.id\n  deleteItem(id)\n}\n\n\u003Cbutton data-id={item.id} onClick={handleDelete}>Delete\u003C\u002Fbutton>\n```\n\n**Rule of thumb:** arrow wrappers are fine for most use cases. Use\n`data-*` attributes on large lists where creating many closures is\nmeasurably expensive.\n",{"id":235,"difficulty":58,"q":236,"a":237},"event-delegation","How does event delegation work in React?","React does not attach individual event listeners directly to each DOM node.\nInstead, it attaches **a single listener** at the root and uses event\nbubbling to catch all events — this is called event delegation.\n\nPrior to React 17, all events were delegated to `document`. In React 17+,\nthey are delegated to the **root DOM container** (`document.getElementById('root')`).\nThis change makes it safer to embed multiple React apps on one page or mix\nReact with non-React code.\n\n```jsx\n\u002F\u002F Conceptually what React does internally (simplified)\nrootElement.addEventListener('click', react_internal_handler)\n\u002F\u002F When a \u003Cbutton> inside is clicked, the event bubbles up to root,\n\u002F\u002F React checks which component was the target, and calls your onClick.\n```\n\nThis is largely transparent to application code, but matters when:\n- Calling `e.stopPropagation()` — stops bubbling before it reaches the\n  React root, so React never sees the event.\n- Using `addEventListener` directly on `document` — fires after React's\n  handler in React 17+.\n\n**Rule of thumb:** rely on React's event system rather than attaching your\nown listeners to `document`; it handles delegation and cleanup for you.\n",{"id":239,"difficulty":33,"q":240,"a":241},"form-handling","How do you handle a form submission in React?","Attach `onSubmit` to the `\u003Cform>` element, call `e.preventDefault()` to\nstop the page reload, then read values from controlled state or uncontrolled\nrefs.\n\n```jsx\nfunction SignupForm() {\n  const [email, setEmail] = useState('')\n  const [password, setPassword] = useState('')\n\n  async function handleSubmit(e) {\n    e.preventDefault()\n    await signUp({ email, password })\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput\n        type=\"email\"\n        value={email}\n        onChange={e => setEmail(e.target.value)}\n      \u002F>\n      \u003Cinput\n        type=\"password\"\n        value={password}\n        onChange={e => setPassword(e.target.value)}\n      \u002F>\n      \u003Cbutton type=\"submit\">Sign up\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n```\n\n**Rule of thumb:** always put `onSubmit` on `\u003Cform>`, not `onClick` on\nthe submit button — the form's handler fires for Enter key presses as well\nas button clicks.\n",{"id":243,"difficulty":58,"q":244,"a":245},"controlled-input","What is a controlled input and why does React prefer it?","A **controlled input** has its `value` (or `checked`) driven by React\nstate. React becomes the single source of truth for the input's content.\n\n```jsx\n\u002F\u002F Controlled — React owns the value\nconst [text, setText] = useState('')\n\u003Cinput value={text} onChange={e => setText(e.target.value)} \u002F>\n\n\u002F\u002F Uncontrolled — DOM owns the value, React reads it on demand\nconst ref = useRef()\n\u003Cinput ref={ref} \u002F>\n\u002F\u002F later: ref.current.value\n```\n\nWhy React prefers controlled:\n- You can validate or transform input on every keystroke.\n- Input state is immediately available in component scope — no need to\n  query the DOM.\n- The input reflects state exactly, so programmatic resets work:\n  `setText('')` clears the field.\n\n**Rule of thumb:** use controlled inputs by default; use uncontrolled when\nintegrating with non-React DOM libraries or when you only need the value\nat submission.\n",{"id":247,"difficulty":58,"q":248,"a":249},"onchange-vs-oninput","What is the difference between onChange and onInput in React?","In the browser, `input` fires on every value change (typing, pasting,\ncutting), while `change` fires only when the element loses focus after a\nvalue change.\n\nReact **normalizes** this: React's `onChange` fires on every value change\n(like the native `input` event), making it consistent regardless of element\ntype. React's `onChange` and native `oninput` are effectively equivalent for\ntext inputs.\n\n```jsx\n\u002F\u002F Fires on every keystroke in React (not just on blur like native 'change')\n\u003Cinput onChange={e => console.log(e.target.value)} \u002F>\n```\n\nReact does expose `onInput` as well, but for controlled inputs `onChange`\nis the standard and recommended handler.\n\n**Rule of thumb:** use `onChange` in React for real-time input tracking.\nKnowing that it behaves like native `oninput` matters when comparing React\nbehavior with vanilla JS.\n",{"id":251,"difficulty":58,"q":252,"a":253},"keyboard-events","How do you handle keyboard events in React?","Use `onKeyDown`, `onKeyUp`, or `onKeyPress` (deprecated — avoid). Read\n`e.key` for the logical key name or `e.code` for the physical key.\n\n```jsx\nfunction SearchBox() {\n  const [query, setQuery] = useState('')\n\n  function handleKeyDown(e) {\n    if (e.key === 'Enter') {\n      search(query)\n    }\n    if (e.key === 'Escape') {\n      setQuery('')\n    }\n  }\n\n  return (\n    \u003Cinput\n      value={query}\n      onChange={e => setQuery(e.target.value)}\n      onKeyDown={handleKeyDown}\n    \u002F>\n  )\n}\n```\n\nFor accessibility, elements that handle keyboard events should also be\nfocusable (native interactive elements are by default; custom elements need\n`tabIndex={0}` and appropriate ARIA roles).\n\n**Rule of thumb:** check `e.key` (logical, locale-aware) rather than\n`e.keyCode` (deprecated numeric code). For modifier keys, check\n`e.ctrlKey`, `e.shiftKey`, `e.altKey`, `e.metaKey`.\n",{"id":255,"difficulty":58,"q":256,"a":257},"class-this-binding","How does 'this' binding work in class component event handlers?","In a class component, `this` inside a regular method is `undefined` when\ncalled as an event handler (because it's passed as a callback — detached\nfrom the instance). There are three common fixes:\n\n```jsx\nclass Counter extends React.Component {\n  constructor(props) {\n    super(props)\n    this.state = { n: 0 }\n    \u002F\u002F Option 1: bind in constructor\n    this.handleClick = this.handleClick.bind(this)\n  }\n\n  handleClick() {\n    this.setState({ n: this.state.n + 1 })\n  }\n\n  render() {\n    return \u003Cbutton onClick={this.handleClick}>{this.state.n}\u003C\u002Fbutton>\n  }\n}\n\n\u002F\u002F Option 2: class field arrow function (auto-binds)\nclass Counter extends React.Component {\n  state = { n: 0 }\n  handleClick = () => {\n    this.setState({ n: this.state.n + 1 })\n  }\n  render() {\n    return \u003Cbutton onClick={this.handleClick}>{this.state.n}\u003C\u002Fbutton>\n  }\n}\n\n\u002F\u002F Option 3: arrow in render (new function per render)\n\u003Cbutton onClick={() => this.handleClick()}>\n```\n\n**Rule of thumb:** class fields (option 2) is the cleanest in modern JS.\nIn function components, this issue doesn't exist at all — another reason\nto prefer them.\n",{"id":259,"difficulty":186,"q":260,"a":261},"throttle-debounce","How do you throttle or debounce an event handler in React?","Wrap the handler with a throttle\u002Fdebounce utility (lodash is most common)\nbut **memoize the wrapper** with `useRef` or `useCallback` so you get a\nstable function reference across renders.\n\n```jsx\nimport { useCallback, useRef } from 'react'\nimport debounce from 'lodash\u002Fdebounce'\n\nfunction SearchInput({ onSearch }) {\n  \u002F\u002F useRef keeps the debounced fn stable across renders\n  const debouncedSearch = useRef(\n    debounce((value) => onSearch(value), 300)\n  ).current\n\n  \u002F\u002F Clean up on unmount\n  useEffect(() => () => debouncedSearch.cancel(), [debouncedSearch])\n\n  return (\n    \u003Cinput onChange={e => debouncedSearch(e.target.value)} \u002F>\n  )\n}\n```\n\nCommon mistake: creating the debounced function inside the component body\nwithout memoization — a new function (with a fresh timer) is created each\nrender, so debouncing never actually fires.\n\n**Rule of thumb:** store debounced\u002Fthrottled functions in `useRef` (not\nrecreated on render) and cancel them on unmount to avoid calling stale\nclosures.\n",{"id":263,"difficulty":58,"q":264,"a":265},"native-event","How do you access the native DOM event from a React SyntheticEvent?","Use `e.nativeEvent` to get the underlying browser `Event` object.\n\n```jsx\nfunction DragZone() {\n  function handleDrop(e) {\n    e.preventDefault()\n    \u002F\u002F SyntheticEvent doesn't expose dataTransfer directly in all React versions\n    const files = e.nativeEvent.dataTransfer?.files\n    console.log(files)\n  }\n  return \u003Cdiv onDrop={handleDrop} onDragOver={e => e.preventDefault()}>Drop here\u003C\u002Fdiv>\n}\n```\n\nReasons you might need `nativeEvent`:\n- Accessing properties not forwarded by the SyntheticEvent wrapper.\n- Passing the event to a non-React library that checks `instanceof Event`.\n- Calling browser-only APIs like `getCoalescedEvents()` for pointer events.\n\n**Rule of thumb:** start with the SyntheticEvent API; only reach for\n`nativeEvent` when you need a property or method that the wrapper doesn't\nexpose.\n",{"id":267,"difficulty":58,"q":268,"a":269},"events-in-list","What is the most efficient way to handle events in a list of items?","Instead of passing a unique arrow function per item (which creates N\nclosures), use a single handler and identify the target via `data-*`\nattributes or `e.currentTarget`.\n\n```jsx\nfunction TodoList({ todos, onToggle }) {\n  function handleClick(e) {\n    const id = e.currentTarget.dataset.id\n    onToggle(id)\n  }\n\n  return (\n    \u003Cul>\n      {todos.map(todo => (\n        \u003Cli key={todo.id}>\n          \u003Cbutton data-id={todo.id} onClick={handleClick}>\n            {todo.text}\n          \u003C\u002Fbutton>\n        \u003C\u002Fli>\n      ))}\n    \u003C\u002Ful>\n  )\n}\n```\n\nFor most lists, arrow functions per item are fine — the overhead is\nnegligible. The `data-*` pattern is worth applying when the list is very\nlong or when the handlers are passed to `React.memo` children.\n\n**Rule of thumb:** profile before optimizing. Use `data-*` delegation when\nyou have hundreds of interactive rows and can measure the improvement.\n",{"id":271,"difficulty":186,"q":272,"a":273},"synthetic-event-async","What happened to SyntheticEvent pooling and what changed in React 17?","Before React 17, React **pooled** SyntheticEvents to reduce garbage\ncollection pressure. After your handler returned, React would reset all\nproperties to `null` and return the event object to the pool.\n\n```jsx\n\u002F\u002F Pre-React 17 bug\nfunction handleChange(e) {\n  setTimeout(() => {\n    console.log(e.target.value)  \u002F\u002F CRASH — e.target is null after handler exits\n  }, 100)\n}\n\n\u002F\u002F Pre-React 17 fix: persist the event\nfunction handleChange(e) {\n  e.persist()  \u002F\u002F remove from pool, keep properties\n  setTimeout(() => {\n    console.log(e.target.value)  \u002F\u002F safe\n  }, 100)\n}\n```\n\n**React 17 removed event pooling.** SyntheticEvents are now regular objects\nthat are not recycled. Accessing them asynchronously is safe, and\n`e.persist()` is a no-op (still exists to avoid breaking old code).\n\n**Rule of thumb:** in React 17+ projects you don't need `e.persist()`. If\nyou see it in a codebase, it's either legacy code or a defensive habit from\nolder React.\n",17,{"description":31},"React event handling interview questions — SyntheticEvent, camelCase events, preventDefault, stopPropagation, passing arguments, controlled inputs, and event delegation.","react\u002Fcomponents\u002Fevent-handling","ouA3PzTAevet2voyeMiClKokS89VxQIssKu_33PPQ1o",{"id":280,"title":281,"body":282,"description":31,"difficulty":33,"extension":34,"framework":10,"frameworkSlug":8,"meta":286,"navigation":37,"order":288,"path":289,"questions":290,"questionsCount":351,"related":106,"seo":352,"seoDescription":353,"stem":354,"subtopic":281,"topic":19,"topicSlug":20,"updated":111,"__hash__":355},"qa\u002Freact\u002Fcomponents\u002Fconditional-rendering.md","Conditional Rendering",{"type":28,"value":283,"toc":284},[],{"title":31,"searchDepth":11,"depth":11,"links":285},[],{"subtopicSlug":287},"conditional-rendering",4,"\u002Freact\u002Fcomponents\u002Fconditional-rendering",[291,295,299,303,307,311,315,319,323,327,331,335,339,343,347],{"id":292,"difficulty":33,"q":293,"a":294},"ways-to-conditionally-render","What are the main ways to conditionally render content in React?","React has four idiomatic patterns:\n\n```jsx\n\u002F\u002F 1. Logical && — render right side only when left is truthy\n{isLoggedIn && \u003CDashboard \u002F>}\n\n\u002F\u002F 2. Ternary — render one of two options\n{isLoggedIn ? \u003CDashboard \u002F> : \u003CLogin \u002F>}\n\n\u002F\u002F 3. Variable \u002F if-else above return\nlet content = isLoggedIn ? \u003CDashboard \u002F> : \u003CLogin \u002F>\nreturn \u003Cmain>{content}\u003C\u002Fmain>\n\n\u002F\u002F 4. Early return — bail out of the component entirely\nif (!isLoggedIn) return \u003CLogin \u002F>\nreturn \u003CDashboard \u002F>\n```\n\nEach has its place:\n- `&&` — one branch only, very readable when the condition is simple.\n- Ternary — exactly two branches.\n- Variable \u002F if-else — complex conditions with more than two outcomes.\n- Early return — guard clause at the top when the component shouldn't\n  render at all in certain states.\n\n**Rule of thumb:** use the simplest form that's still readable. If a\nternary has nested ternaries, it's time for an if-else or a variable.\n",{"id":296,"difficulty":33,"q":297,"a":298},"and-operator","How does the && operator work for conditional rendering?","JavaScript's `&&` returns the **last evaluated operand** — not necessarily\na boolean. React renders whatever value appears on the right side of `&&`\nwhen the left side is truthy.\n\n```jsx\nconst count = 5\nreturn (\n  \u003Cdiv>\n    {count > 0 && \u003CBadge count={count} \u002F>}\n    {\u002F* → renders \u003CBadge \u002F> because (count > 0) is true *\u002F}\n  \u003C\u002Fdiv>\n)\n```\n\nWhen the condition is `false`, `&&` short-circuits and returns `false`.\nReact treats `false` as \"render nothing\" — no output.\n\n**Rule of thumb:** `{condition && \u003CElement \u002F>}` is idiomatic React. The\ncondition should be a boolean; if in doubt, cast it: `{!!value && \u003CX \u002F>}`.\n",{"id":300,"difficulty":58,"q":301,"a":302},"falsy-zero-bug","What is the \"falsy zero\" bug with the && operator?","`&&` returns the **left operand** when it is falsy. If that operand is `0`,\nReact renders the number `0` (since `0` is a valid renderable value).\n\n```jsx\nconst messages = []    \u002F\u002F length is 0\n\n\u002F\u002F ❌ Renders \"0\" when messages is empty\nreturn \u003Cdiv>{messages.length && \u003CMessageList items={messages} \u002F>}\u003C\u002Fdiv>\n\n\u002F\u002F ✅ Force the left side to a boolean\nreturn \u003Cdiv>{messages.length > 0 && \u003CMessageList items={messages} \u002F>}\u003C\u002Fdiv>\n\n\u002F\u002F ✅ Or use Boolean()\nreturn \u003Cdiv>{Boolean(messages.length) && \u003CMessageList items={messages} \u002F>}\u003C\u002Fdiv>\n\n\u002F\u002F ✅ Or use a ternary\nreturn \u003Cdiv>{messages.length ? \u003CMessageList items={messages} \u002F> : null}\u003C\u002Fdiv>\n```\n\n**Rule of thumb:** never use `count &&` or `array.length &&` directly.\nAlways compare: `count > 0 &&` or `array.length > 0 &&`. The same trap\nexists for any number that could be `0`.\n",{"id":304,"difficulty":33,"q":305,"a":306},"ternary-rendering","How do you use a ternary for conditional rendering?","The ternary expression (`condition ? a : b`) is a JavaScript expression and\nis legal inside JSX `{}`. It's the idiomatic way to render one of two\nalternatives.\n\n```jsx\nfunction AuthStatus({ isLoggedIn, username }) {\n  return (\n    \u003Cheader>\n      {isLoggedIn\n        ? \u003Cspan>Welcome, {username}!\u003C\u002Fspan>\n        : \u003Ca href=\"\u002Flogin\">Sign in\u003C\u002Fa>\n      }\n    \u003C\u002Fheader>\n  )\n}\n```\n\nUse `null` for the false branch when you want to render nothing:\n\n```jsx\n{isAdmin ? \u003CAdminPanel \u002F> : null}\n\u002F\u002F Equivalent to:\n{isAdmin && \u003CAdminPanel \u002F>}\n```\n\n**Rule of thumb:** ternaries are great for exactly two outcomes. For more\nthan two, a variable or a helper function is cleaner.\n",{"id":308,"difficulty":58,"q":309,"a":310},"when-to-use-which","When should you use if\u002Felse, ternary, or && for conditional rendering?","Choose based on the number of outcomes and complexity:\n\n| Pattern | Best for |\n|---------|----------|\n| `&&` | Single optional element; condition is a simple boolean |\n| Ternary | Exactly two alternatives; fits on one or two lines |\n| `if\u002Felse` above return | Multiple alternatives; complex conditions; shared logic before branching |\n| Early `return` | Guard clause — component has nothing to show in this state |\n\n```jsx\n\u002F\u002F && — simple optional\n{hasError && \u003CErrorBanner message={error} \u002F>}\n\n\u002F\u002F Ternary — two outcomes\n{loading ? \u003CSpinner \u002F> : \u003CContent data={data} \u002F>}\n\n\u002F\u002F if\u002Felse — three outcomes\nlet body\nif (loading) body = \u003CSpinner \u002F>\nelse if (error) body = \u003CError message={error} \u002F>\nelse body = \u003CContent data={data} \u002F>\nreturn \u003Cmain>{body}\u003C\u002Fmain>\n\n\u002F\u002F Early return — guard clause\nif (!user) return null\nreturn \u003CProfile user={user} \u002F>\n```\n\n**Rule of thumb:** default to simplicity. Reach for `&&` first, ternary\nfor two branches, if\u002Felse for three or more. Never nest ternaries more\nthan one level deep.\n",{"id":312,"difficulty":33,"q":313,"a":314},"returning-null","How do you render nothing from a component?","Return `null`. React renders nothing to the DOM but the component remains\nmounted — its `useEffect` hooks still run and refs still attach.\n\n```jsx\nfunction Tooltip({ visible, text }) {\n  if (!visible) return null\n  return \u003Cdiv className=\"tooltip\">{text}\u003C\u002Fdiv>\n}\n```\n\nOther falsy values behave differently:\n- `undefined` — React 18+ allows returning `undefined` from a component\n  (was an error in older versions). Treated like `null`.\n- `false` — valid child; renders nothing.\n- `0` — renders the digit `0`. Careful!\n- Empty string `''` — renders nothing visible but creates a text node.\n\n**Rule of thumb:** return `null` (not `false` or `undefined`) when you\nwant a component to render nothing — it's explicit and unambiguous.\n",{"id":316,"difficulty":58,"q":317,"a":318},"display-none-vs-conditional","What is the difference between CSS display:none and conditional rendering?","- **CSS `display:none`** — the element is in the DOM, painted, and React's\n  tree, but invisible. State, refs, effects, and event listeners are all live.\n- **Conditional rendering** — the element is not in the DOM. When the\n  condition becomes false, React unmounts the component: state is reset,\n  effects clean up, and refs detach.\n\n```jsx\n\u002F\u002F CSS approach — DOM node always present, just hidden\n\u003Cdiv style={{ display: isVisible ? 'block' : 'none' }}>\n  \u003CExpensiveWidget \u002F>   {\u002F* still mounted, effects running *\u002F}\n\u003C\u002Fdiv>\n\n\u002F\u002F Conditional — component unmounts when isVisible is false\n{isVisible && \u003CExpensiveWidget \u002F>}\n```\n\nUse cases:\n- Prefer conditional rendering when you want fresh state on each appearance.\n- Prefer `display:none` when mounting\u002Funmounting is expensive (e.g. a heavy\n  widget) or when you must preserve internal state across hides.\n\n**Rule of thumb:** default to conditional rendering. Use CSS visibility only\nwhen remounting is measurably expensive or state preservation is required.\n",{"id":320,"difficulty":33,"q":321,"a":322},"conditional-class","How do you conditionally apply a CSS class in JSX?","Use a ternary or template literal inside `className`:\n\n```jsx\n\u002F\u002F Ternary — toggle between two class names\n\u003Cbutton className={isActive ? 'btn btn-active' : 'btn'}>Click\u003C\u002Fbutton>\n\n\u002F\u002F Template literal — build up from base + optional modifier\n\u003Cdiv className={`card ${isHighlighted ? 'card-highlighted' : ''}`}>…\u003C\u002Fdiv>\n\n\u002F\u002F For multiple conditional classes, clsx\u002Fclassnames library is cleaner\nimport clsx from 'clsx'\n\u003Cdiv className={clsx('card', { 'card-highlighted': isHighlighted, 'card-error': hasError })}>\n  …\n\u003C\u002Fdiv>\n```\n\nAvoid complex string concatenation inline — it becomes unreadable quickly.\n\n**Rule of thumb:** for more than one or two conditional classes, add `clsx`\n(or `classnames`) to the project — it handles undefined\u002Ffalse values\ncleanly and the API is easy to scan.\n",{"id":324,"difficulty":58,"q":325,"a":326},"role-based-rendering","How do you render different content based on user role or permission?","Extract the guard logic into a dedicated component or hook to keep the\nrendering logic clean.\n\n```jsx\n\u002F\u002F Simple inline\n{user.role === 'admin' && \u003CAdminPanel \u002F>}\n\n\u002F\u002F Reusable gate component\nfunction Can({ role, children }) {\n  const { user } = useAuth()\n  return user.role === role ? children : null\n}\n\n\u002F\u002F Usage\n\u003CCan role=\"admin\">\n  \u003CDeleteButton \u002F>\n\u003C\u002FCan>\n\n\u002F\u002F Or a hook\nfunction usePermission(requiredRole) {\n  const { user } = useAuth()\n  return user.role === requiredRole\n}\n\nconst canDelete = usePermission('admin')\n{canDelete && \u003CDeleteButton \u002F>}\n```\n\n**Rule of thumb:** keep auth\u002Fpermission logic out of individual components.\nA `\u003CCan>` component or `usePermission` hook keeps it testable and reusable\nacross the app.\n",{"id":328,"difficulty":58,"q":329,"a":330},"switch-rendering","Can you use a switch statement for conditional rendering?","Yes, but a switch statement can't go directly inside JSX. Extract it into\na helper function or variable.\n\n```jsx\nfunction StatusBadge({ status }) {\n  function renderBadge() {\n    switch (status) {\n      case 'success': return \u003Cspan className=\"badge green\">Success\u003C\u002Fspan>\n      case 'error':   return \u003Cspan className=\"badge red\">Error\u003C\u002Fspan>\n      case 'loading': return \u003CSpinner \u002F>\n      default:        return null\n    }\n  }\n\n  return \u003Cdiv className=\"status\">{renderBadge()}\u003C\u002Fdiv>\n}\n```\n\nAn object map is often cleaner than switch for this pattern:\n\n```jsx\nconst BADGE = {\n  success: \u003Cspan className=\"badge green\">Success\u003C\u002Fspan>,\n  error:   \u003Cspan className=\"badge red\">Error\u003C\u002Fspan>,\n  loading: \u003CSpinner \u002F>,\n}\n\nreturn \u003Cdiv>{BADGE[status] ?? null}\u003C\u002Fdiv>\n```\n\n**Rule of thumb:** object maps are more idiomatic React than switch\nstatements for rendering; switch is fine when you need fallthrough or `break`\nbehavior.\n",{"id":332,"difficulty":58,"q":333,"a":334},"avoid-nested-ternaries","How do you avoid deeply nested ternaries in JSX?","Extract the logic to a variable, early return, or helper function before\nthe `return`.\n\n```jsx\n\u002F\u002F ❌ Nested ternary — hard to read\nreturn (\n  \u003Cdiv>\n    {loading\n      ? \u003CSpinner \u002F>\n      : error\n        ? \u003CError message={error} \u002F>\n        : data\n          ? \u003CDataView data={data} \u002F>\n          : \u003CEmpty \u002F>}\n  \u003C\u002Fdiv>\n)\n\n\u002F\u002F ✅ Variable approach\nlet content\nif (loading)     content = \u003CSpinner \u002F>\nelse if (error)  content = \u003CError message={error} \u002F>\nelse if (data)   content = \u003CDataView data={data} \u002F>\nelse             content = \u003CEmpty \u002F>\n\nreturn \u003Cdiv>{content}\u003C\u002Fdiv>\n\n\u002F\u002F ✅ Helper component\nfunction AsyncContent({ loading, error, data }) {\n  if (loading) return \u003CSpinner \u002F>\n  if (error)   return \u003CError message={error} \u002F>\n  if (!data)   return \u003CEmpty \u002F>\n  return \u003CDataView data={data} \u002F>\n}\n```\n\n**Rule of thumb:** if a ternary needs to be nested, refactor to if\u002Felse\nor extract a component. A long chain of nested ternaries is a refactoring\nsignal, not a clever trick.\n",{"id":336,"difficulty":58,"q":337,"a":338},"loading-error-states","What is the pattern for handling loading and error states in rendering?","The guard-clause \u002F early-return pattern keeps the happy path last:\n\n```jsx\nfunction UserProfile({ userId }) {\n  const { data: user, loading, error } = useUser(userId)\n\n  if (loading) return \u003CSkeleton \u002F>\n  if (error)   return \u003CErrorMessage error={error} \u002F>\n  if (!user)   return null\n\n  \u002F\u002F Happy path — no nesting, no clutter\n  return (\n    \u003Carticle>\n      \u003Ch1>{user.name}\u003C\u002Fh1>\n      \u003Cp>{user.bio}\u003C\u002Fp>\n    \u003C\u002Farticle>\n  )\n}\n```\n\nThis pattern is sometimes called \"bail early, render late.\" Each guard\nhandles one sad path and returns, leaving the main render clean.\n\n**Rule of thumb:** load state first, error state second, empty\u002Fnull state\nthird, happy path last. This order prevents accidentally rendering\nundefined properties.\n",{"id":340,"difficulty":33,"q":341,"a":342},"short-circuit-evaluation","What is short-circuit evaluation and how does it apply to conditional rendering?","Short-circuit evaluation means JavaScript stops evaluating an expression as\nsoon as the result is determined:\n- In `A && B` — if `A` is falsy, `B` is never evaluated.\n- In `A || B` — if `A` is truthy, `B` is never evaluated.\n\nReact leverages `&&` for conditional rendering because when the condition\nis false, the right-hand component is not evaluated (and thus not rendered):\n\n```jsx\n\u002F\u002F UserMenu is never evaluated when isLoggedIn is false\n{isLoggedIn && \u003CUserMenu user={user} \u002F>}\n\n\u002F\u002F Useful for expensive renders or components that crash on missing data\n{user && user.isAdmin && \u003CAdminPanel \u002F>}\n```\n\n**Rule of thumb:** short-circuit with `&&` when you have one optional\nelement and no fallback. Use `||` for default values, not for conditional\nrendering — `{value || \u003CFallback \u002F>}` renders `\u003CFallback \u002F>` whenever\n`value` is falsy (including `0` and `''`).\n",{"id":344,"difficulty":58,"q":345,"a":346},"nullish-coalescing","What is the nullish coalescing operator and when is it useful in JSX?","`??` returns the right operand only when the left is `null` or `undefined`\n(not for `0`, `''`, or `false`). This makes it safer than `||` for default\nvalues.\n\n```jsx\n\u002F\u002F || treats 0 and '' as falsy — may swallow valid values\n\u003Cp>Score: {score || 'No score'}\u003C\u002Fp>\n\u002F\u002F If score is 0, renders \"No score\" — wrong!\n\n\u002F\u002F ?? treats only null\u002Fundefined as \"missing\"\n\u003Cp>Score: {score ?? 'No score'}\u003C\u002Fp>\n\u002F\u002F If score is 0, renders \"0\" — correct\n\n\u002F\u002F Common in JSX for optional labels, counts, or display values\n\u003Ch2>{user.displayName ?? user.email}\u003C\u002Fh2>\n```\n\n**Rule of thumb:** use `??` for \"provide a fallback when the value is\nmissing.\" Use `||` only when you intentionally want `0`, `false`, and `''`\nto also trigger the fallback.\n",{"id":348,"difficulty":186,"q":349,"a":350},"suspense-lazy-conditional","How do React.lazy and Suspense relate to conditional rendering?","`React.lazy` lets you load a component's code on demand. `Suspense`\nprovides a fallback to show while the lazy component loads — effectively\na built-in conditional-rendering pattern for async code splitting.\n\n```jsx\nimport { lazy, Suspense } from 'react'\n\nconst AdminPanel = lazy(() => import('.\u002FAdminPanel'))\n\nfunction App({ user }) {\n  return (\n    \u003CSuspense fallback={\u003CSpinner \u002F>}>\n      {user.isAdmin && \u003CAdminPanel \u002F>}\n    \u003C\u002FSuspense>\n  )\n}\n```\n\nWhen `\u003CAdminPanel \u002F>` is first rendered, React suspends, the nearest\n`\u003CSuspense>` shows `\u003CSpinner \u002F>`, and the bundle chunk loads in the\nbackground. On completion React retries the render and shows the panel.\n\n**Rule of thumb:** combine `lazy` + `Suspense` with normal conditional\nrendering. `Suspense` handles the *loading* state of the import; your\n`&&` or ternary handles the *permission* or *visibility* condition.\n",15,{"description":31},"React conditional rendering interview questions — ternary, &&, null, guard clauses, loading states, CSS display vs conditional mounting, and clean multi-condition patterns.","react\u002Fcomponents\u002Fconditional-rendering","rh-A8_S8gjIU82IuQOu1zQklJ_cBcEkCZg5aTFr7yCQ",{"id":357,"title":358,"body":359,"description":31,"difficulty":33,"extension":34,"framework":10,"frameworkSlug":8,"meta":363,"navigation":37,"order":365,"path":366,"questions":367,"questionsCount":440,"related":106,"seo":441,"seoDescription":442,"stem":443,"subtopic":444,"topic":19,"topicSlug":20,"updated":111,"__hash__":445},"qa\u002Freact\u002Fcomponents\u002Flists-keys.md","Lists Keys",{"type":28,"value":360,"toc":361},[],{"title":31,"searchDepth":11,"depth":11,"links":362},[],{"subtopicSlug":364},"lists-keys",5,"\u002Freact\u002Fcomponents\u002Flists-keys",[368,372,376,380,384,388,392,396,400,404,408,412,416,420,424,428,432,436],{"id":369,"difficulty":33,"q":370,"a":371},"render-list","How do you render a list of items in React?","Use `Array.map` to transform a data array into an array of React elements.\nReact accepts an array of elements as a valid child.\n\n```jsx\nfunction FruitList({ fruits }) {\n  return (\n    \u003Cul>\n      {fruits.map(fruit => (\n        \u003Cli key={fruit.id}>{fruit.name}\u003C\u002Fli>\n      ))}\n    \u003C\u002Ful>\n  )\n}\n\n\u002F\u002F Usage\nconst fruits = [\n  { id: 1, name: 'Apple' },\n  { id: 2, name: 'Banana' },\n  { id: 3, name: 'Cherry' },\n]\n\u003CFruitList fruits={fruits} \u002F>\n```\n\nEach element in the mapped array must have a `key` prop so React can track\nit across renders.\n\n**Rule of thumb:** every `.map()` that produces JSX needs a `key` on the\noutermost returned element. If you forget it, React will warn in development\nand may produce incorrect diffs.\n",{"id":373,"difficulty":33,"q":374,"a":375},"what-is-key","What is the key prop and why is it required for lists?","`key` is a **special React prop** that gives each element in a list a\nstable identity. React uses it during reconciliation to match elements\nbetween renders and decide what to update, move, or unmount.\n\n```jsx\n{todos.map(todo => (\n  \u003CTodoItem key={todo.id} todo={todo} \u002F>\n  \u002F\u002F         ▲ unique, stable identifier\n))}\n```\n\nWithout keys, React falls back to positional matching: element 0 in the\nold list = element 0 in the new list. If you insert or delete items, React\nmay reuse the wrong component instance, leading to bugs like stale state,\nwrong animation, or incorrect DOM content.\n\nKeys must be:\n- **Unique among siblings** (not globally unique).\n- **Stable** — the same item should have the same key across renders.\n\n**Rule of thumb:** always key from your data's natural unique identifier\n(database id, UUID, slug). Never use array index as a default.\n",{"id":377,"difficulty":58,"q":378,"a":379},"index-as-key","What problems arise when you use the array index as a key?","Index keys break when the list can be **reordered, filtered, or have items\ninserted\u002Fdeleted**.\n\n```jsx\n\u002F\u002F ❌ Index key — dangerous for mutable lists\n{items.map((item, i) => \u003CRow key={i} data={item} \u002F>)}\n\n\u002F\u002F ✅ Stable id key\n{items.map(item => \u003CRow key={item.id} data={item} \u002F>)}\n```\n\nThe problem: React identifies components by key. If you delete item at\nindex 0, everything shifts down by one — the component at index 1 now has\nkey `0`, so React thinks it's the same component as the old index-0 element.\nReact will update props but **not reset state**. This causes:\n- Controlled input fields retaining the wrong value.\n- Animations starting from the wrong position.\n- Incorrect checkboxes or selection states.\n\n**Rule of thumb:** use index as key only when: the list is read-only and\nnever reordered, items have no stable IDs, and the items have no internal\nstate (pure display).\n",{"id":381,"difficulty":58,"q":382,"a":383},"good-key","What makes a good key?","A good key is:\n1. **Unique among siblings** — two siblings can't share a key; siblings in\n   different lists can.\n2. **Stable** — the same data item has the same key across every render.\n3. **String or number** — React converts numbers to strings internally.\n\n```jsx\n\u002F\u002F ✅ Database primary key — best option\n\u003CItem key={item.id} \u002F>\n\n\u002F\u002F ✅ Slug\u002Fname if guaranteed unique per list\n\u003CTab key={tab.slug} \u002F>\n\n\u002F\u002F ✅ Composite key when no single field is unique\n\u003CCell key={`${row.id}-${col.name}`} \u002F>\n\n\u002F\u002F ❌ Math.random() — new key every render, defeats the purpose\n\u003CItem key={Math.random()} \u002F>\n\n\u002F\u002F ❌ Index — unstable when list mutates\n\u003CItem key={index} \u002F>\n```\n\nGenerating keys with `Math.random()` or `Date.now()` forces React to\nunmount and remount every item on every render — worse than no key at all.\n\n**Rule of thumb:** use the data's natural ID. If your data has no ID,\ngenerate one at the time the data is created (not at render time).\n",{"id":385,"difficulty":33,"q":386,"a":387},"key-placement","Where does the key prop need to be placed?","The `key` must be on the **outermost element** returned from the map\ncallback — the element React is tracking. It does not need to be (and\ncannot be) read by the component that receives it.\n\n```jsx\n\u002F\u002F ✅ key on the outer element\n{products.map(p => (\n  \u003CProductCard key={p.id} product={p} \u002F>\n))}\n\n\u002F\u002F ❌ key on an inner element — React doesn't see it for list tracking\n{products.map(p => (\n  \u003Cdiv>\n    \u003CProductCard key={p.id} product={p} \u002F>  {\u002F* wrong position *\u002F}\n  \u003C\u002Fdiv>\n))}\n\n\u002F\u002F If the callback returns a Fragment, key goes on the Fragment\n{products.map(p => (\n  \u003CReact.Fragment key={p.id}>\n    \u003Cdt>{p.name}\u003C\u002Fdt>\n    \u003Cdd>{p.description}\u003C\u002Fdd>\n  \u003C\u002FReact.Fragment>\n))}\n```\n\n**Rule of thumb:** key goes on the tag you write in the `.map()` return,\nnot inside it.\n",{"id":389,"difficulty":33,"q":390,"a":391},"key-global-unique","Does the key prop need to be globally unique?","No. Keys only need to be **unique among siblings** — elements within the\nsame list at the same level. The same key value can appear in a different\nlist elsewhere.\n\n```jsx\nfunction Page() {\n  return (\n    \u003C>\n      \u003Cul>\n        {fruits.map(f => \u003Cli key={f.id}>{f.name}\u003C\u002Fli>)}\n      \u003C\u002Ful>\n      \u003Cul>\n        {\u002F* key={1} here doesn't conflict with key={1} above *\u002F}\n        {vegetables.map(v => \u003Cli key={v.id}>{v.name}\u003C\u002Fli>)}\n      \u003C\u002Ful>\n    \u003C\u002F>\n  )\n}\n```\n\nReact tracks keys per list context, not globally across the component tree.\n\n**Rule of thumb:** your IDs only need to be unique within the array you're\nmapping. Composite keys like `${listName}-${item.id}` are redundant unless\nyou have a single flat array mixing different entity types.\n",{"id":393,"difficulty":58,"q":394,"a":395},"reconciliation-keys","What is reconciliation and how do keys affect it?","**Reconciliation** is the process React uses to efficiently update the DOM\nby comparing the new virtual DOM tree with the previous one. React's\ndiffing algorithm has a key heuristic: elements of different types are\nalways replaced; elements of the same type are updated.\n\nKeys extend this heuristic to **lists**: React matches old and new elements\nby key, then decides:\n- Same key, same type → update props in place.\n- New key → mount a new component.\n- Missing key (was present before) → unmount the old component.\n- Same key, different position → React can reorder the DOM node efficiently.\n\n```\nBefore: [A(key=1), B(key=2), C(key=3)]\nAfter:  [C(key=3), A(key=1), B(key=2)]\n\nWith keys: React moves DOM nodes — no unmount\u002Fremount.\nWithout keys: React updates all three by position — potentially wrong.\n```\n\n**Rule of thumb:** correct keys make list operations O(n) instead of\nO(n²); they also prevent state from leaking to the wrong component when\nitems shift.\n",{"id":397,"difficulty":58,"q":398,"a":399},"duplicate-keys","What happens if two siblings have the same key?","React warns in development and exhibits undefined behavior — typically it\nrenders only one of the duplicates and drops the other, or updates the\nwrong component on subsequent renders.\n\n```jsx\n\u002F\u002F ❌ Duplicate keys — unpredictable behavior\n{items.map(item => (\n  \u003CRow key={item.category} data={item} \u002F>\n  \u002F\u002F If multiple items share the same category, keys collide\n))}\n\n\u002F\u002F ✅ Use a truly unique field or compose a unique key\n{items.map(item => (\n  \u003CRow key={item.id} data={item} \u002F>\n))}\n```\n\nIn production, no warning is shown — the bug is silent. This is one reason\nto run development builds regularly.\n\n**Rule of thumb:** if you see the \"Encountered two children with the same\nkey\" warning in the console, your mapping produces non-unique keys — check\nwhich field you're using.\n",{"id":401,"difficulty":58,"q":402,"a":403},"key-prop-readable","Can a component read its own key prop?","No. `key` is **reserved by React** and is not forwarded to the component\nas a prop. If you try to access `props.key` inside the component, you'll\nget `undefined`.\n\n```jsx\nfunction Row({ key, name }) {\n  \u002F\u002F key is always undefined here — React consumed it\n  return \u003Ctr>\u003Ctd>{name}\u003C\u002Ftd>\u003C\u002Ftr>\n}\n\n\u002F\u002F If the component needs the id, pass it explicitly\n{items.map(item => (\n  \u003CRow key={item.id} id={item.id} name={item.name} \u002F>\n))}\n```\n\nThe same is true for `ref` — both are meta-props handled by React before\nthe component sees its props.\n\n**Rule of thumb:** if a component needs its own identifier, pass it as a\nseparate prop (e.g. `id`). Treat `key` as infrastructure, not data.\n",{"id":405,"difficulty":58,"q":406,"a":407},"no-id-data","How do you handle keys when your data has no unique IDs?","Options in rough order of preference:\n\n1. **Add an ID at the source.** If you control the API, add an `id` field.\n2. **Generate IDs when data enters the app** — not at render time.\n\n```jsx\n\u002F\u002F When you receive data, enrich it once\nimport { randomUUID } from 'crypto'\n\nconst items = rawData.map(d => ({ ...d, id: randomUUID() }))\n```\n\n3. **Composite key** from fields that together are unique:\n\n```jsx\n{countries.map(c => (\n  \u003CCountryRow key={`${c.code}-${c.region}`} country={c} \u002F>\n))}\n```\n\n4. **Index as last resort** — only if the list is static (never reordered\n   or mutated) and items have no internal state.\n\n**Rule of thumb:** generate IDs at data-entry time (API response handler,\nform submission), not inside `.map()`. A key generated in `.map()` is a\nnew key every render — React unmounts and remounts every item.\n",{"id":409,"difficulty":58,"q":410,"a":411},"cost-of-no-key","What is the actual cost of not providing a key?","Without a key, React falls back to positional diffing, which causes:\n\n1. **Incorrect state association** — when items reorder, state (including\n   controlled input values, scroll position, open\u002Fclosed accordion) follows\n   the position, not the item.\n\n2. **Unnecessary re-renders and DOM mutations** — React may update the props\n   of an existing component rather than reorder it, doing more work.\n\n3. **Console warning** — in development, `Warning: Each child in a list\n   should have a unique \"key\" prop`.\n\n```jsx\n\u002F\u002F List re-ordered from [A, B, C] to [C, A, B]\n\u002F\u002F Without keys: React updates A→C, B→A, C→B (three updates + DOM writes)\n\u002F\u002F With keys: React moves DOM nodes (one reorder)\n```\n\nThe correctness bug is worse than the performance bug: stale input values\nor wrong selection state are visible to users.\n\n**Rule of thumb:** treat missing keys as a bug, not a warning. Fix them\nbefore they reach production.\n",{"id":413,"difficulty":58,"q":414,"a":415},"render-component-list","How do you render a list of different component types based on data?","Use an object map or a switch inside the map callback to select the\ncomponent type dynamically.\n\n```jsx\nconst BLOCK_COMPONENTS = {\n  text:    TextBlock,\n  image:   ImageBlock,\n  video:   VideoBlock,\n  divider: DividerBlock,\n}\n\nfunction PageContent({ blocks }) {\n  return (\n    \u003Carticle>\n      {blocks.map(block => {\n        const Block = BLOCK_COMPONENTS[block.type]\n        if (!Block) return null\n        return \u003CBlock key={block.id} {...block} \u002F>\n      })}\n    \u003C\u002Farticle>\n  )\n}\n```\n\nNote that `Block` (uppercase) is required because JSX uses the case to\ndistinguish between a DOM element (string) and a component (variable reference).\n\n**Rule of thumb:** the object-map pattern scales better than a switch as\nthe number of types grows, and makes it easy to add new block types in one\nplace.\n",{"id":417,"difficulty":58,"q":418,"a":419},"index-reorder-bug","What happens when list items reorder and you used index keys?","React matches old element at index N to new element at index N. If items\nreorder, the component at each position gets the props of the new item but\n**retains the state of the old item** — because from React's perspective\nit's the \"same\" component (same key = same index).\n\n```jsx\n\u002F\u002F Scenario: [Alice, Bob, Carol] → [Carol, Alice, Bob] (sorted)\n\u002F\u002F With index keys:\n\u002F\u002F   Index 0 was Alice, now Carol → React updates props: Alice→Carol\n\u002F\u002F   But Alice's text input still shows Alice's draft (state is index-0's)\n```\n\nVisually: the displayed name changes, but any controlled input value,\nopen dropdown, or animation state stays — it belongs to the position, not\nthe item.\n\n**Rule of thumb:** this is the canonical \"index key\" bug. Any time a list\ncan be sorted, filtered, or have items added\u002Fremoved, use stable IDs.\n",{"id":421,"difficulty":58,"q":422,"a":423},"acceptable-index-key","When is it acceptable to use index as a key?","The React team's guidance: index as key is safe only when **all three**\nconditions hold:\n1. The list is **static** — it never reorders or has items inserted\u002Fdeleted.\n2. Items have **no stable IDs** in the data.\n3. The list is **never re-filtered** — count and order don't change.\n\n```jsx\n\u002F\u002F Acceptable: read-only, ordered, no unique id, no internal state\nconst STEPS = ['Install', 'Configure', 'Deploy']\n{STEPS.map((step, i) => (\n  \u003Cli key={i}>{step}\u003C\u002Fli>\n))}\n```\n\nIf the list comes from an API and may change at any time, don't use index.\n\n**Rule of thumb:** if you have to think about whether index is safe, your\ndata should have IDs. The safe scenarios are narrow; don't give yourself\npermission to use index keys broadly.\n",{"id":425,"difficulty":58,"q":426,"a":427},"nested-lists","How do nested lists affect key requirements?","Each level of nesting is its own sibling context. Keys at one level don't\ninteract with keys at another. However, every `.map()` at every level\nneeds its own `key`.\n\n```jsx\nfunction Table({ rows }) {\n  return (\n    \u003Ctable>\n      \u003Ctbody>\n        {rows.map(row => (\n          \u003Ctr key={row.id}>   {\u002F* key for row siblings *\u002F}\n            {row.cells.map(cell => (\n              \u003Ctd key={cell.colId}>{cell.value}\u003C\u002Ftd>  {\u002F* key for cell siblings *\u002F}\n            ))}\n          \u003C\u002Ftr>\n        ))}\n      \u003C\u002Ftbody>\n    \u003C\u002Ftable>\n  )\n}\n```\n\n**Rule of thumb:** every `.map()` call needs a `key`, at every nesting\nlevel. The keys only need to be unique among siblings at that level —\n`row.id` and `cell.colId` don't need to be in different namespaces.\n",{"id":429,"difficulty":58,"q":430,"a":431},"key-vs-ref","What is the difference between key and ref in React?","Both are special \"meta-props\" handled by React before the component sees\nits props, but they serve completely different purposes:\n\n| | `key` | `ref` |\n|---|---|---|\n| Purpose | List identity for reconciliation | Imperative access to DOM node \u002F component instance |\n| Readable by component | No (`props.key` is `undefined`) | Via `useRef` \u002F `forwardRef` |\n| When to use | Every element in a `.map()` list | Direct DOM manipulation, focus management, measuring |\n| Value type | String or number | Object from `useRef()` or callback |\n\n```jsx\nconst inputRef = useRef()\n\n\u002F\u002F key for list tracking, ref for focus imperatively\n{items.map(item => (\n  \u003Cinput key={item.id} ref={item.isFocused ? inputRef : null} \u002F>\n))}\n```\n\n**Rule of thumb:** `key` is for React's reconciler (list diffing); `ref`\nis for your code to poke the DOM. They are unrelated features that happen\nto both be invisible to `props`.\n",{"id":433,"difficulty":58,"q":434,"a":435},"fragment-in-lists","What is the role of React.Fragment in lists?","When a list item needs to render **multiple sibling elements** without a\nwrapper DOM node, use `\u003CReact.Fragment key={...}>` — the short `\u003C>…\u003C\u002F>`\nsyntax doesn't support `key`.\n\n```jsx\nfunction DefinitionList({ items }) {\n  return (\n    \u003Cdl>\n      {items.map(item => (\n        \u002F\u002F Short fragment syntax doesn't accept key — use long form\n        \u003CReact.Fragment key={item.id}>\n          \u003Cdt>{item.term}\u003C\u002Fdt>\n          \u003Cdd>{item.definition}\u003C\u002Fdd>\n        \u003C\u002FReact.Fragment>\n      ))}\n    \u003C\u002Fdl>\n  )\n}\n```\n\nIf you wrap in a `\u003Cdiv>` instead, the resulting `\u003Cdl>\u003Cdiv>\u003Cdt>…\u003Cdd>…\u003C\u002Fdiv>\u003C\u002Fdl>`\nis invalid HTML and breaks styling.\n\n**Rule of thumb:** whenever you need `key` on a Fragment, use\n`\u003CReact.Fragment key={id}>`. It's the only valid way to key a fragment.\n",{"id":437,"difficulty":186,"q":438,"a":439},"virtual-dom-diffing","How does React's virtual DOM use keys for diffing list elements?","React's reconciliation algorithm compares the previous and next virtual DOM\ntrees in a single pass per level. For lists specifically, it builds a\n**key-to-fiber map** of the old children, then for each child in the new\nlist it looks up the key:\n\n- **Key found, same type** → update props, keep the existing fiber (DOM\n  node), move it if position changed.\n- **Key found, different type** → unmount old, mount new.\n- **Key not found** → mount new fiber.\n- **Old key no longer in new list** → unmount.\n\n```\nOld: [\u003Cli key=\"a\">, \u003Cli key=\"b\">, \u003Cli key=\"c\">]\nNew: [\u003Cli key=\"c\">, \u003Cli key=\"a\">, \u003Cli key=\"b\">]\n\nReact: key \"c\" moved from index 2 → 0, DOM node reused.\n       keys \"a\" and \"b\" shifted, DOM nodes reused.\nResult: 0 unmounts, 0 mounts, 3 DOM moves.\n```\n\nWithout keys React would compare index-by-index and update all three\nelements' props even though the content is the same.\n\n**Rule of thumb:** keys let React reorder DOM nodes cheaply instead of\ndoing redundant prop patches. This is why keys are a performance AND\ncorrectness feature.\n",18,{"description":31},"React lists and keys interview questions — key prop, reconciliation, index as key pitfalls, stable keys, Fragment in lists, and rendering nested arrays.","react\u002Fcomponents\u002Flists-keys","Lists and Keys","PqeIWQPL16QElLjRR0piFnipmLYPvjvm8nl6oVP4PTU",1782244096614]