React & Redux
React fundamentals — components, hooks, state and effects, lifecycle, rendering, controlled inputs, and keys.
15 questions
JuniorTheoryVery commonIn React, what is the difference between controlled and uncontrolled inputs?
In React, what is the difference between controlled and uncontrolled inputs?
A controlled input has its value driven by React state via a value prop and an onChange handler — state is the single source of truth and the DOM only reflects it. An uncontrolled input keeps its value in the DOM with no value prop; you read it via a ref.
Common mistakes
- ✗Setting
valuewithout anonChange, making the input read-only and frozen - ✗Mixing
valueanddefaultValueon the same input - ✗Reaching for a
refto read a controlled input instead of reading state
Follow-up questions
- →Why does a
valueprop without anonChangemake the input read-only? - →When is an uncontrolled input with a
refthe better choice?
JuniorTheoryVery commonWhat do the core React hooks useState, useEffect, and useContext do?
What do the core React hooks useState, useEffect, and useContext do?
useState adds local state to a function component, returning the current value and a setter that re-renders on change. useEffect runs side effects (subscriptions, fetches, DOM work) after render, with a dependency array controlling when it re-runs and an optional cleanup. useContext reads the nearest provider's value for a given context, re-rendering when it changes.
Common mistakes
- ✗Calling hooks conditionally or in loops, breaking React's call-order tracking
- ✗Omitting the
useEffectdependency array, so it runs after every render - ✗Mutating state in place instead of passing a new value to the setter
Follow-up questions
- →Why must hooks be called in the same order on every render?
- →When does a
useEffectcleanup function run?
JuniorTheoryVery commonIn the UI library React, how do props differ from state?
In the UI library React, how do props differ from state?
Props are inputs passed down from a parent — read-only inside the receiving component, which must never mutate them. State is data a component owns and manages internally; updating it (via setState or a useState setter) schedules a re-render. Props flow one way (parent to child); state is local. Changing either triggers a re-render of the component.
Common mistakes
- ✗Mutating props directly instead of treating them as read-only inputs
- ✗Storing in state a value that is fully derived from props, causing drift
- ✗Thinking a child can push changes back up by reassigning a prop
Follow-up questions
- →How does a child component communicate a change back up to its parent?
- →When should derived data live in state versus be computed during render?
JuniorTheoryCommonBeyond lists, how can changing a React key reset a component's state?
Beyond lists, how can changing a React key reset a component's state?
A key is the identity React uses to decide whether an element across two renders is the same instance. If the key stays the same, React updates the existing instance and keeps its state; if the key changes, React unmounts the old instance and mounts a fresh one, discarding state.
Common mistakes
- ✗Thinking a key only matters inside lists and never elsewhere
- ✗Expecting a key change to keep state rather than remount the component
- ✗Believing a key stores or restores state snapshots
Follow-up questions
- →When is keying a single component on a record id a clean reset pattern?
- →What is the difference between updating and remounting an instance?
JuniorTheoryCommonWhat are the main lifecycle phases of a React class component?
What are the main lifecycle phases of a React class component?
A class component has three phases. Mounting runs constructor, getDerivedStateFromProps, render, then componentDidMount. Updating runs shouldComponentUpdate, render, getSnapshotBeforeUpdate, then componentDidUpdate. Unmounting runs componentWillUnmount.
Common mistakes
- ✗Starting data fetching in the
constructoror inrenderinstead ofcomponentDidMount - ✗Forgetting cleanup in
componentWillUnmount, leaking timers or listeners - ✗Thinking
componentDidMountruns again on every update
Follow-up questions
- →Which lifecycle method is the right place to remove an event listener?
- →Which hooks replace
componentDidMountandcomponentWillUnmountin function components?
JuniorTheoryCommonIn React, what arguments does the class setState method take?
In React, what arguments does the class setState method take?
The first argument is either an object merged into state, or an updater function (prevState, props) => partialState — use the function form when the next state depends on the previous to avoid stale-state bugs. Reading this.state right after the call still shows the old value.
Common mistakes
- ✗Passing an object when the next state depends on the previous, causing lost updates under batching
- ✗Expecting
this.stateto reflect the new value immediately aftersetState - ✗Thinking
setStatereplaces the whole state object rather than shallow-merging it
Follow-up questions
- →Why does the updater function form avoid stale-state bugs that the object form has?
- →When would you use the second callback argument instead of
componentDidUpdate?
JuniorTheoryCommonWhat is the virtual DOM in React, and why do list items need a key?
What is the virtual DOM in React, and why do list items need a key?
The virtual DOM is a lightweight in-memory tree describing the UI. On each render React diffs the new tree against the previous one (reconciliation) and applies the minimal real-DOM mutations: different element types replace the subtree, same types patch props. A key gives each list child a stable identity so React matches elements across renders instead of recreating them, preserving state and avoiding wrong reuse.
Common mistakes
- ✗Using the array index as a
keyfor a reorderable or filterable list - ✗Thinking the virtual DOM is inherently faster than the real DOM rather than a diffing layer
- ✗Believing reconciliation deep-compares everything instead of using type/key heuristics
Follow-up questions
- →Why is using the array index as a
keyrisky when items can reorder? - →What does React do when an element's type changes between two renders?
MiddleTheoryCommonIn React, when do you use useMemo, useCallback, and useEffect?
In React, when do you use useMemo, useCallback, and useEffect?
useEffect runs side effects after render — subscriptions, fetches, DOM work — with cleanup on deps change or unmount. useMemo memoizes an expensive computed value across renders, keyed by its dependencies. useCallback memoizes a function reference (a special case of useMemo) so it stays stable for memoized children or effect deps. Overusing them on cheap values costs more than it saves.
Common mistakes
- ✗Wrapping trivially cheap values in
useMemo, where the overhead exceeds the saving - ✗Confusing
useMemo(memoizes a value) withuseCallback(memoizes a function) - ✗Expecting
useEffectto run before paint like a synchronous computation
Follow-up questions
- →Why is
useCallback(fn, deps)equivalent touseMemo(() => fn, deps)? - →When does memoizing a value actually hurt performance instead of helping?
MiddleTheoryCommonWhy does React treat setState as asynchronous, and what is batching?
Why does React treat setState as asynchronous, and what is batching?
For performance, React defers applying setState rather than mutating state and re-rendering on the spot. It collects several updates triggered in the same tick and flushes them as a single re-render — this is batching. React 18 auto-batches across promises and timers too.
Common mistakes
- ✗Reading
this.stateright aftersetStateand seeing the old value - ✗Calling
setStatewith an object several times expecting each to apply separately - ✗Assuming batching only happens inside React event handlers even on React 18
Follow-up questions
- →How does React 18 automatic batching differ from the legacy behavior?
- →How would you read the committed state right after an update lands?
JuniorTheoryOccasionalWhat are container and presentational components in React?
What are container and presentational components in React?
A presentational (dumb) component is concerned only with how things look — it takes props and renders markup, holding little state and no data logic. A container (smart) component is concerned with how things work — it fetches data, reads the store, handles events, and feeds children.
Common mistakes
- ✗Mixing data fetching into a presentational component, hurting its reuse
- ✗Thinking the distinction is about the root JSX element rather than responsibility
- ✗Treating the split as a hard rule rather than a guideline, over-fragmenting the tree
Follow-up questions
- →Why does keeping a presentational component data-free improve its reuse?
- →How do hooks blur the old container/presentational boundary?
MiddleTheoryOccasionalShould a React class fetch data in componentDidMount or componentWillMount?
Should a React class fetch data in componentDidMount or componentWillMount?
Use componentDidMount. It runs after the first render commits, so a setState with the fetched data triggers a second render that paints the result. componentWillMount runs before the first render, where a setState does not schedule a re-render, and it is deprecated.
Common mistakes
- ✗Believing a
setStateincomponentWillMountschedules a re-render - ✗Fetching inside
render, firing a new request on every render - ✗Using the deprecated
componentWillMountin new code
Follow-up questions
- →Why does a
setStateincomponentWillMountnot cause a visible update? - →What
useEffectdependency array reproducescomponentDidMountbehavior?
MiddleTheoryOccasionalWhat happens if you set key={Math.random()} on a React component?
What happens if you set key={Math.random()} on a React component?
Every render produces a new random key, so React sees a different identity each time and unmounts the old instance to mount a fresh one. The component loses all state, re-runs mount/unmount effects, loses focus and scroll, and pays the full remount cost.
Common mistakes
- ✗Using a random or index key to silence a warning, causing remounts or bugs
- ✗Thinking a remount keeps state because the same component type renders
- ✗Believing
Reactignores or stabilizes a non-deterministic key automatically
Follow-up questions
- →Why does a per-render key cause mount/unmount effects to fire repeatedly?
- →What makes a good stable key for a list of records?
SeniorDebuggingOccasionalReview this React component: what bugs would you flag?
Review this React component: what bugs would you flag?
Main bug: useEffect has no dependency array, so it refetches every render — and each setLocation triggers another render, an effective loop; give it [props.locationId]. spotTimes is an ARRAY of single-key objects but is read as spotTimes[s.id] — wrong shape; build one object or a Map keyed by id. The mapped <div> has no key, breaking reconciliation. Minor: use ===, and render a loading state for location.
Common mistakes
- ✗Missing the no-dependency-array bug that causes the effect to refetch on every render
- ✗Not noticing
spotTimesis an array of objects but indexed as if it were a keyed map - ✗Overlooking the missing
keyon the mapped list elements
Follow-up questions
- →Why does an effect with no dependency array combined with
setStatecreate a refetch loop? - →How would you reshape
spotTimessospotTimes[s.id]reads correctly?
MiddleTheoryRareIn React, how does useLayoutEffect differ from useEffect?
In React, how does useLayoutEffect differ from useEffect?
Both have the same signature and dependency-array semantics, but they run at different times. useEffect runs asynchronously after the browser has painted, so it never blocks visual updates — the default for most side effects.
Common mistakes
- ✗Defaulting to
useLayoutEffectand blocking paint whereuseEffectwould do - ✗Expecting
useEffectto run before the browser paints - ✗Measuring layout in
useEffectand seeing a flicker before the correction
Follow-up questions
- →Why can measuring a DOM node in
useEffectcause a visible flicker? - →Why does overusing
useLayoutEffectrisk dropping frames?
SeniorTheoryRareHow do React hooks work internally, and why the Rules of Hooks?
How do React hooks work internally, and why the Rules of Hooks?
React stores a component's hooks as an ordered list (a linked list of hook records) on its fiber. On each render it walks that list in call order, matching the Nth hook call to the Nth stored record to recover its state. There are no names — position is the only identity.
Common mistakes
- ✗Thinking hooks are keyed by name rather than by call order
- ✗Calling a hook inside an
ifor loop, shifting later hooks onto wrong records - ✗Believing the Rules of Hooks are only a lint style convention
Follow-up questions
- →What concretely breaks if a
useStatecall is wrapped in anif? - →Why can two components reuse the same hook order without colliding?