Exit
Learn Mode
Play Instead

React / Learn

Master 100 concepts with detailed explanations.

1basic

What will happen when this code runs?

function App() { const [count, setCount] = useState(0); useEffect(() => { setCount(count + 1); }); return <div>{count}</div>; }
Infinite re-render loop

useEffect without a dependency array runs after every render. Setting state inside it triggers another render, which triggers the effect again - causing an infinite loop.

2basic

Which hook should you use to memoize an expensive calculation?

useMemo

useMemo memoizes the result of a computation. useCallback memoizes a function reference. useMemo is the right choice when you want to cache a derived value rather than a function.

3basic

What does the key prop do in a list of React elements?

Helps React identify which items changed, were added, or removed

Keys help React's reconciler match elements between renders. Without stable keys, React may re-create DOM nodes unnecessarily or produce incorrect diffs.

4basic

What is the output of this component on initial render?

function Counter() { const [n, setN] = useState(5); return ( <button onClick={() => setN(n => n + 1)}> {n} </button> ); }
5

useState(5) initialises the state to 5. On the initial render the value of n is 5, so the button shows 5. The functional updater form n => n + 1 is only called when the button is clicked.

5medium

When does React batch state updates (React 18+)?

In all contexts: event handlers, timeouts, promises, and native events

React 18 introduced automatic batching, which batches state updates from all sources (event handlers, timeouts, Promises, native event listeners) into a single re-render. Prior to React 18, batching only happened in React-controlled event handlers.

6medium

What is the purpose of React.StrictMode?

Helps detect potential problems by intentionally double-invoking certain functions in development

StrictMode intentionally double-invokes render methods, state initializers, and effects (in development only) to surface side-effects that should be pure. It has no effect in production.

7basic

What does useCallback return?

A memoized version of the callback function

useCallback(fn, deps) returns a memoized function that only changes if one of the deps changes. It is useful when passing callbacks to child components that are wrapped in React.memo to prevent unnecessary re-renders.

8medium

What is the correct way to update a nested property in state without mutation?

const [user, setUser] = useState({ name: 'Alice', address: { city: 'NYC' } });
setUser({ ...user, address: { ...user.address, city: 'LA' } });

React state must be treated as immutable. The correct approach is to spread the outer object and spread the nested object with the updated field. Options A, C, and D mutate the existing state reference, which React may not detect as a change.

9basic

What does the useRef hook primarily store?

A mutable ref object whose .current property does not trigger re-renders when mutated

useRef returns a mutable object { current: initialValue }. Mutating .current does not cause a re-render, making it useful for DOM references and persisting mutable values across renders without causing updates.

10basic

What is the difference between controlled and uncontrolled components?

Controlled components have their value managed by React state; uncontrolled components manage their own internal DOM state

In a controlled component, form data is handled by React state via value + onChange. In an uncontrolled component, form data is handled by the DOM itself and you read it with a ref when needed.

11advanced

What will this code log?

function App() { const [x, setX] = useState(0); const handleClick = () => { setX(x + 1); setX(x + 1); setX(x + 1); console.log(x); }; return <button onClick={handleClick}>{x}</button>; }
0 and the button shows 1

State updates are asynchronous. All three setX(x + 1) calls read the same stale closure value of x (0), so they all schedule a single update to 1. The console.log runs synchronously and still sees 0. The button re-renders showing 1.

12basic

What does React.memo do?

Skips re-rendering a component if its props have not changed (shallow comparison)

React.memo is a higher-order component that performs a shallow comparison of props. If props are equal to the previous render, React skips the render and reuses the last rendered output.

13advanced

In which phase does useLayoutEffect run?

After DOM mutations but before the browser paints

useLayoutEffect fires synchronously after all DOM mutations but before the browser has a chance to paint. This is useful for reading layout or synchronously re-styling the DOM to prevent a visual flicker. useEffect, by contrast, runs after the paint.

14basic

What is Context in React used for?

Passing data through the component tree without prop drilling

React Context provides a way to share values (theme, locale, auth user, etc.) between components at any depth without manually passing them as props through every intermediate component.

15basic

What does the dependency array in useEffect control?

When the effect re-runs - it re-runs when any value in the array changes

The dependency array tells React when to re-run the effect. An empty array [] means run once on mount. No array means run after every render. A populated array means run when any listed dependency changes between renders.

16basic

What does this useReducer code print when the button is clicked?

function reducer(state, action) { switch (action.type) { case 'inc': return { count: state.count + 1 }; default: return state; } } function App() { const [state, dispatch] = useReducer(reducer, { count: 0 }); return ( <button onClick={() => dispatch({ type: 'inc' })}> {state.count} </button> ); }
Shows 0 initially, then increments by 1 on each click

useReducer initializes state to { count: 0 }. Dispatching { type: 'inc' } calls the reducer, which returns a new state object with count incremented by 1. React re-renders the component with the updated state.

17medium

What is the output of this component after clicking the button once?

function App() { const [count, setCount] = useState(0); const handleClick = () => { setCount(c => c + 1); setCount(c => c + 1); setCount(c => c + 1); }; return <button onClick={handleClick}>{count}</button>; }
The button shows 3 because each functional updater receives the latest pending state

When you use the functional updater form (c => c + 1), each call receives the most recently queued state, not the stale closure value. Three successive functional updaters each add 1, so count goes from 0 to 3.

18basic

Which rule about hooks is enforced by the React linter?

Hooks must be called at the top level of a component, not inside loops, conditions, or nested functions

React relies on the order of hook calls staying the same between renders. Calling hooks conditionally or inside loops can break this order. The eslint-plugin-react-hooks enforces this rule automatically.

19advanced

What happens to the event object after an event handler returns in legacy React (before React 17)?

The event object is pooled and its properties are set to null, making async access return null

React used a synthetic event pool in versions before React 17. After the event handler returned, the event was recycled and all properties nullified. React 17 removed event pooling, so this is no longer an issue in modern React.

20medium

What does React.lazy() do?

Enables code splitting by letting you render a dynamic import as a component

React.lazy() accepts a function that calls a dynamic import() and returns a Promise. Combined with Suspense, it lets React load that component's bundle on demand, reducing the initial bundle size.

21basic

What is printed to the console when this component mounts?

function App() { useEffect(() => { console.log('effect'); return () => console.log('cleanup'); }, []); console.log('render'); return null; }
'render' then 'effect'

The component body (and its console.log('render')) executes first during rendering. After React commits to the DOM, useEffect runs and logs 'effect'. The cleanup function runs when the component unmounts, not on mount.

22medium

What does React.createPortal do?

Renders children into a DOM node that exists outside the parent component's DOM hierarchy

ReactDOM.createPortal(children, domNode) renders children into a different DOM node, typically document.body, while keeping them in the React tree. This is commonly used for modals and tooltips that need to escape overflow:hidden containers.

23medium

What is the correct way to forward a ref to a DOM element inside a function component?

Wrap the component with React.forwardRef and attach the second argument to the DOM element

React.forwardRef((props, ref) => ...) gives the component access to the ref passed by its parent. You attach that ref to the DOM element (or child component) you want to expose. Without forwardRef, the ref prop is not forwarded.

24advanced

What will be logged by this component in React 18 StrictMode on mount?

function App() { useEffect(() => { console.log('mount'); return () => console.log('unmount'); }, []); return null; }
'mount', 'unmount', 'mount'

In React 18 StrictMode (development only), effects are intentionally mounted, unmounted, then mounted again to help surface bugs from missing cleanup. You will see 'mount', 'unmount', 'mount' in the console.

25medium

What does the useTransition hook return?

A boolean isPending and a startTransition function for marking low-priority updates

useTransition() returns [isPending, startTransition]. Wrapping a state update in startTransition marks it as non-urgent, letting React keep the UI responsive. isPending is true while the transition is in progress.

26advanced

What does useDeferredValue do?

Returns a deferred version of a value that may lag behind the real value during urgent renders

useDeferredValue(value) returns a version of the value that React can defer updating during urgent renders. It lets you keep the UI responsive by rendering the expensive part (like a filtered list) with a slightly stale value.

27advanced

What does this custom hook return on the first render?

function usePrevious(value) { const ref = useRef(); useEffect(() => { ref.current = value; }); return ref.current; } // Used as: const prev = usePrevious(42);
undefined, because the effect runs after the render and the ref has not been set yet

On the first render, useRef() initializes to undefined (no initial value given). The effect that sets ref.current = value runs after the render, so the return value on first render is undefined. On subsequent renders it returns the previous value.

28basic

Which of these correctly creates and consumes a Context value?

const Ctx = createContext(default); at module level, wrap tree with <Ctx.Provider value={v}>, consume with useContext(Ctx)

createContext should be called at module level (outside components). The Provider wraps the subtree and provides a value. Any descendant can call useContext(Ctx) to subscribe to that value and re-render when it changes.

29basic

What is a React Fragment and why is it useful?

A Fragment lets you group multiple elements without adding an extra DOM node

React requires a single root element, but sometimes adding a wrapper div pollutes the DOM. <React.Fragment> (or the shorthand <>) groups multiple children without adding any real DOM node.

30basic

What triggers a React component to re-render?

When the component's state changes, its parent re-renders, or a consumed context value changes

A component re-renders when its own state changes, when its parent re-renders (unless blocked by React.memo), or when a context value it subscribes to changes. All three triggers can independently cause a re-render.

31medium

What is the output of this JSX?

function App() { return ( <div> {false} {null} {undefined} {0} <span>done</span> </div> ); }
Renders '0done' because 0 is the only falsy value that JSX renders

In JSX, false, null, and undefined render nothing. However, the number 0 is a valid React child and does render as the character '0'. This is a common bug when writing {array.length && <Component />} - it renders 0 when the array is empty.

32basic

What is prop drilling and what is the recommended React solution?

Prop drilling is passing props through many component layers; the solution is to use Context or a state manager

Prop drilling happens when you pass data through many intermediate components that don't need it themselves. React Context (or external state managers like Zustand or Redux) solves this by making data available to any component in the tree.

33medium

What happens when you use an array index as the key in a dynamic list?

React may incorrectly reuse DOM nodes and component state when items are added, removed, or reordered

When items are reordered or removed, the index of each item changes. React matches old and new elements by key, so it may reuse the wrong DOM node or component state, causing subtle bugs like incorrect input values.

34medium

What does an error boundary catch?

Errors thrown during rendering, in lifecycle methods, and in constructors of child components

Error boundaries catch JavaScript errors during rendering, in lifecycle methods, and in constructors of the whole child tree. They do not catch errors in event handlers, async code, server-side rendering, or errors thrown inside the error boundary itself.

35medium

What is the correct lifecycle method pair to implement an error boundary in a class component?

componentDidCatch and static getDerivedStateFromError

static getDerivedStateFromError(error) updates state so the next render shows a fallback UI. componentDidCatch(error, info) is for logging the error. Together they form a complete error boundary. Function components cannot be error boundaries yet.

36basic

What is the difference between state and props in React?

Props are read-only data passed from a parent; state is mutable data owned and managed by the component itself

Props flow down from parent to child and are read-only inside the receiving component. State is local, mutable data that the component manages itself. Changing state schedules a re-render; mutating props directly is forbidden.

37advanced

What does useImperativeHandle do?

Lets a child component expose specific methods to its parent via a ref

useImperativeHandle(ref, () => ({ method })) customizes the value that the parent sees when it holds a ref to the child component. It is always paired with forwardRef and lets you expose a controlled API instead of the raw DOM node.

38basic

Which of these is a valid custom hook?

const useData = () => { const [d, setD] = useState(null); return d; }

A custom hook is any function whose name starts with 'use' and that calls React hooks inside it. Option B is an arrow function starting with 'use' that uses useState, making it a valid custom hook. Option A does not start with 'use'.

39basic

What is the output of this component?

const ThemeContext = createContext('light'); function Child() { const theme = useContext(ThemeContext); return <p>{theme}</p>; } function App() { return ( <ThemeContext.Provider value="dark"> <Child /> </ThemeContext.Provider> ); }
'dark' because the Provider overrides the default value for all descendants

The default value passed to createContext is only used when a component does not have a matching Provider above it. Because Child is wrapped by <ThemeContext.Provider value='dark'>, useContext returns 'dark'.

40medium

What does Suspense do in React?

Lets you declaratively specify a fallback UI while child components or data are loading

React.Suspense wraps components that may need to wait (for lazy imports or data fetching via Suspense-compatible libraries). While waiting, React renders the fallback prop. When the component is ready, React replaces the fallback with the real UI.

41medium

What is the result of calling useState with a function argument?

const [value, setValue] = useState(() => computeExpensiveDefault());
React calls the function only on the first render to compute the initial state

Passing a function (lazy initializer) to useState tells React to call it only once during the initial render. Subsequent renders ignore the function entirely. This avoids running expensive computations on every render.

42advanced

What is a React Server Component?

A component that runs only on the server, has no client-side JavaScript, and can access backend resources directly

React Server Components (RSC) run exclusively on the server. They can access databases and file systems directly, send zero JavaScript to the client, and cannot use state or effects. They are a distinct concept from SSR.

43advanced

What is the difference between useEffect and useLayoutEffect?

useEffect runs asynchronously after paint; useLayoutEffect runs synchronously after DOM mutations but before paint

useEffect is asynchronous and runs after the browser has painted. useLayoutEffect is synchronous and fires right after DOM mutations, before the browser paints. Use useLayoutEffect only when you need to read or modify layout to avoid a visual flicker.

44medium

What happens if you forget to return a cleanup function from useEffect when adding an event listener?

useEffect(() => { window.addEventListener('resize', handleResize); }, []);
The event listener leaks and continues to run after the component unmounts

Without a cleanup function returning () => window.removeEventListener('resize', handleResize), the listener persists after unmount. This creates a memory leak and may call handlers that reference unmounted component state.

45basic

What is component composition in React?

Building complex UI by combining smaller, focused components via props and the children prop

React favors composition over inheritance. You build flexible UIs by creating small, focused components and combining them. The children prop and render props patterns are the primary tools. React's own documentation advises against class inheritance for sharing UI logic.

46medium

What value does useRef return and how does it persist across renders?

useRef returns the same object reference across all renders; only .current can change

React creates the ref object once on mount and returns the same object reference on every subsequent render. Because the object identity never changes, mutating .current does not trigger a re-render.

47basic

In what order do these lifecycle phases occur in a function component?

The component renders, the DOM is updated, then useEffect runs

React follows a strict order: (1) the component function executes (render phase), (2) React updates the DOM (commit phase), (3) useEffect callbacks fire (after paint). This mirrors componentDidMount/componentDidUpdate in class components.

48medium

What does this code demonstrate and what is the potential problem?

function SearchResults({ query }) { const results = useMemo( () => expensiveFilter(allData, query), [query] ); return <List items={results} />; }
It demonstrates correct useMemo usage; expensiveFilter only reruns when query changes

This is correct useMemo usage. expensiveFilter is only called when query changes. If allData is defined outside the component (module-level constant), it does not need to be in the dependency array because it never changes.

49medium

What is wrong with this useCallback usage?

function Parent() { const onClick = useCallback(() => { console.log('clicked'); }, []); return <Child onClick={onClick} />; } const Child = ({ onClick }) => <button onClick={onClick}>Click</button>;
Child is not wrapped in React.memo, so useCallback provides no benefit here

useCallback only prevents re-renders when the child is wrapped in React.memo. Without React.memo on Child, Parent's re-render causes Child to re-render regardless of whether onClick is the same reference. The memoization is wasted.

50advanced

What is the output when the button is clicked once?

function App() { const [count, setCount] = useState(0); const ref = useRef(count); const handleClick = () => { setCount(count + 1); console.log(ref.current); }; return <button onClick={handleClick}>{count}</button>; }
Logs 0 and shows 1

ref.current was set to 0 when the component first rendered and is never updated afterward. setCount schedules a re-render, but the console.log runs synchronously in the same event handler, reading the stale ref.current value of 0. The button re-renders and shows 1.

51basic

What is the purpose of the children prop in React?

It receives whatever JSX is placed between a component's opening and closing tags

When you write <Card><p>Hello</p></Card>, React passes <p>Hello</p> as props.children to Card. The component can then render {children} wherever it wants, enabling flexible component composition patterns.

52basic

What is conditional rendering in React and which patterns are commonly used?

Returning different JSX based on props or state, using if/else, ternary expressions, or the && operator

Conditional rendering means returning different JSX based on runtime conditions. Common patterns are: if/else before the return, ternary (condition ? A : B) inline, and short-circuit (condition && <Component />) for optional elements.

53medium

What does this render?

function App() { const items = []; return <div>{items.length && <ul><li>Item</li></ul>}</div>; }
A div containing the number 0

items.length is 0, which is falsy but React renders the number 0 as text. The && short-circuits and returns the left operand (0) when it is falsy. To fix this, use !!items.length && ... or items.length > 0 && ...

54basic

Which of the following is NOT a valid way to call a hook?

Calling useState inside an if block within a function component

Hooks must not be called conditionally. Calling useState (or any hook) inside an if block means the hook may or may not be called depending on the condition, which violates the Rules of Hooks and breaks the hook call order React depends on.

55medium

What does this component render on the first click?

function App() { const [items, setItems] = useState(['a', 'b']); const add = () => { items.push('c'); setItems(items); }; return <button onClick={add}>{items.length}</button>; }
Shows 3 on the button but React may not re-render because it sees the same array reference

Array.push mutates the existing array in place. React does a shallow comparison of the old and new state references. Because setItems(items) passes the same reference back, React may bail out of re-rendering. You should use setItems([...items, 'c']) instead.

56medium

What is the PureComponent class equivalent in function components?

React.memo, which shallowly compares props and skips re-renders when they have not changed

React.PureComponent implements shouldComponentUpdate with a shallow props and state comparison. The equivalent for function components is React.memo, which does the same shallow props comparison and skips re-rendering when props are unchanged.

57medium

What does React's reconciliation algorithm use to decide whether to update or replace a DOM element?

It compares element type and key; same type means update in place, different type means unmount and remount

React's diffing algorithm first compares element types. If the type is the same, it updates the existing DOM node. If the type differs, it destroys the old subtree and builds a new one. The key prop helps React match elements in lists across renders.

58basic

What will this render?

function App() { return ( <> <p>First</p> <p>Second</p> </> ); }
Two p tags with no wrapping DOM element

The shorthand <> ... </> is a React.Fragment. It groups multiple children without adding any extra DOM node. The browser only sees the two <p> elements with no parent wrapper.

59advanced

Why might a useMemo or useCallback call hurt rather than help performance?

Because memoization has its own cost: storing the previous value and comparing dependencies on every render

Every useMemo and useCallback call adds overhead: React must store the previous value, run the dependency comparison, and manage the cached closure. For cheap computations or components that always re-render anyway, this overhead outweighs the savings.

60advanced

What is the correct way to read a DOM element's width in a ref after the component mounts?

Read ref.current.offsetWidth inside useLayoutEffect with an empty dependency array

DOM layout properties like offsetWidth are only available after the DOM has been updated. useLayoutEffect runs synchronously after DOM mutations and before paint, making it the right place to read layout. Reading during render returns null because the DOM node does not yet exist.

61advanced

What does startTransition do differently from a regular state update?

It marks the update as non-urgent, so React can interrupt and defer it to keep the UI responsive

startTransition tells React that the wrapped state update is a non-urgent transition. React can interrupt, pause, or restart the transition work if higher-priority updates (like user input) come in, keeping the UI interactive.

62medium

What is the render prop pattern?

Passing a function as a prop that a component calls to determine what to render

The render prop pattern shares code between components by passing a function prop that returns JSX. The host component calls this function and renders its result, giving the caller full control over the rendered output while the host component manages logic.

63medium

What happens to child component state when a parent re-renders?

Child state is preserved as long as the child stays mounted at the same position in the tree

React preserves the state of a component as long as it stays mounted at the same position in the component tree with the same type and key. A parent re-rendering does not reset child state unless the child is unmounted and remounted.

64advanced

What happens when you pass the same key to two sibling components of different types?

React treats them independently because they have different types, despite sharing the same key

Keys are only meaningful within the same parent context. React uses both type and key together when diffing. Two siblings with the same key but different types are still treated as separate elements and will each unmount and remount if they swap positions.

65basic

What does this code do on each render?

function App() { const [count, setCount] = useState(0); const double = useMemo(() => count * 2, [count]); return <p>{double}</p>; }
Recalculates count * 2 only when count changes; otherwise returns the cached result

useMemo with [count] in the dependency array only recomputes the value when count changes between renders. If count is the same as the previous render, React returns the cached value without running the factory function.

66medium

What is automatic batching in React 18 and what problem does it solve?

It groups multiple state updates from any context into a single re-render, reducing unnecessary renders

Before React 18, only updates inside synthetic event handlers were batched. React 18 automatically batches updates from promises, setTimeout, and native events too, so multiple setState calls in any context cause a single re-render instead of one render per call.

67advanced

Which API lets you opt out of automatic batching in React 18 when you need an immediate re-render?

ReactDOM.flushSync

ReactDOM.flushSync(fn) forces React to flush all state updates inside fn synchronously and immediately, bypassing automatic batching. It is useful when you need the DOM to update before reading a layout value.

68basic

What does this code print when the component first mounts and then unmounts?

useEffect(() => { const id = setInterval(() => console.log('tick'), 1000); return () => clearInterval(id); }, []);
Prints 'tick' every second while mounted; stops printing when unmounted

The empty dependency array means the effect runs once on mount, starting the interval. The cleanup function (returning clearInterval) runs when the component unmounts, stopping the interval. This is the correct pattern for timers in useEffect.

69advanced

How does React.lazy and Suspense handle a chunk that fails to load?

The error propagates and must be caught by a parent error boundary

If a lazy import rejects (e.g., network failure), React throws the error and the nearest error boundary catches it. Without an error boundary, the error surfaces as an uncaught exception. Suspense only handles the loading state, not the error state.

70basic

What is the correct way to render a list of items in React?

const fruits = ['apple', 'banana', 'cherry'];
{fruits.map(f => <li key={f}>{f}</li>)}

Array.map returns a new array of React elements, which React can render. forEach returns undefined and cannot be embedded in JSX. The for loop is not a valid JSX expression. Always include a stable key prop when mapping over lists.

71medium

What is wrong with reading context inside a non-component function?

function fetchUser() { const auth = useContext(AuthContext); return fetch('/api/user/' + auth.id); }
useContext can only be called inside React function components or custom hooks, not plain functions

Hooks can only be called inside React function components or custom hooks (functions whose name starts with 'use'). Calling useContext inside a plain utility function like fetchUser violates the Rules of Hooks and throws at runtime.

72medium

What does React do when a component renders null?

React renders nothing to the DOM but keeps the component instance alive with its state intact

Returning null from a component renders nothing to the DOM, but the component instance (and its state) remains mounted. This is different from conditional rendering that removes the component from the tree entirely.

73medium

Which statement about useReducer vs useState is correct?

useReducer is preferable when state logic involves multiple sub-values or when the next state depends on complex transitions

useReducer shines when state logic is complex: multiple related state values, transitions that depend on the current state, or when you want a Redux-like pattern for predictability. For simple independent values, useState is more concise.

74medium

What will this component display after one click?

function App() { const [a, setA] = useState(1); const [b, setB] = useState(10); const click = () => { setA(a + 1); setB(b + 1); }; console.log('render'); return <button onClick={click}>{a},{b}</button>; }
Logs 'render' once because React batches both updates into a single re-render

React 18 batches all state updates within the same event handler into a single re-render. Both setA and setB are called in one click handler, so React processes them together and triggers only one re-render, logging 'render' once.

75basic

What is the correct pattern for fetching data in a function component?

Fetch data inside useEffect with the appropriate dependencies and store the result in state

Data fetching belongs inside useEffect because it is a side effect. You start the fetch, then call setState when the data arrives, which triggers a re-render with the loaded data. The dependency array controls when refetching occurs.

76basic

What does this JSX compile to?

const el = <h1 className="title">Hello</h1>;
React.createElement('h1', { className: 'title' }, 'Hello')

JSX is syntactic sugar for React.createElement calls. The Babel/SWC transform converts <h1 className='title'>Hello</h1> into React.createElement('h1', { className: 'title' }, 'Hello'), which returns a plain JavaScript object describing the element.

77advanced

What is a stale closure bug in the context of React hooks?

When a hook callback closes over a state or prop value from an earlier render and uses that outdated value

A stale closure occurs when a function (like an effect or event handler) captures a variable's value at the time it was created, then uses that stale value on a later render where the variable has changed. The fix is either adding the value to the dependency array or using a ref.

78advanced

What does this pattern accomplish?

const callbackRef = useRef(callback); callbackRef.current = callback; useEffect(() => { const handler = () => callbackRef.current(); window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); }, []);
It adds a stable event listener that always calls the latest callback without re-registering on each render

This is the 'latest ref' pattern. Storing callback in a ref and always updating callbackRef.current means the effect runs once (empty deps) with a stable handler function, but that handler always calls the latest version of callback via the ref.

79medium

What does React do when it encounters two consecutive renders that produce the same output?

React skips DOM updates where the virtual DOM diff shows no changes

React's reconciler diffs the new virtual DOM against the previous one. Where no difference is found, it skips the corresponding DOM update. The component still re-renders (its function still runs), but React avoids unnecessary DOM mutations.

80basic

What is the mount phase of a React function component?

The first time the component renders and React commits its output to the DOM

The mount phase is the initial render: the component function runs for the first time, React creates the DOM nodes, and effects with [] or no dependency run for the first time. State is initialized, and refs receive their DOM node.

81basic

What does the unmount phase do in a React function component?

Runs cleanup functions returned from useEffect and useLayoutEffect, then removes the DOM nodes

When a component unmounts, React runs all cleanup functions returned from its effects. This is the right place to cancel subscriptions, clear timers, and remove event listeners. After cleanup, React removes the component's DOM nodes.

82basic

What is wrong with this code?

function App() { if (Math.random() > 0.5) { const [val, setVal] = useState(''); } return null; }
Hooks must not be called conditionally; this violates the Rules of Hooks

Calling useState inside an if statement is a direct violation of the Rules of Hooks. React relies on the order of hook calls being identical on every render. Conditional invocation breaks this order and causes unexpected behavior or errors.

83medium

What is the difference between a React element and a React component?

A React element is a plain object describing what to render; a React component is a function or class that returns elements

A React element is an immutable plain object created by React.createElement (or JSX). It describes what you want on screen. A React component is a function (or class) that accepts props and returns elements. Components produce elements; elements describe the UI.

84advanced

What is the output when the component below renders?

function App() { const [show, setShow] = useState(true); return ( <div> {show ? <Child key="a" /> : <Child key="b" />} </div> ); } function Child() { const [n, setN] = useState(0); return <button onClick={() => setN(n + 1)}>{n}</button>; }
Toggling show resets the child's count to 0 because the key changes, causing unmount and remount

Even though both JSX branches render the same Child component type, they have different keys ('a' vs 'b'). When the key changes, React treats it as a completely different element: it unmounts the old Child and mounts a new one, resetting its state to 0.

85medium

How do you prevent a child component from re-rendering when the parent re-renders but props have not changed?

Wrap the child component with React.memo so it performs a shallow props comparison

React.memo(ChildComponent) wraps the component and performs a shallow comparison of its props between renders. If all props are the same reference, React reuses the last rendered output and skips calling the component function again.

86advanced

What does the second argument to React.memo do?

It is a custom comparison function that returns true if props are equal (skip render) and false if different (re-render)

React.memo(Component, arePropsEqual) accepts an optional second argument. If arePropsEqual(prevProps, nextProps) returns true, React skips the render. If it returns false, React re-renders. Note this is the opposite of shouldComponentUpdate's return value.

87medium

What is the purpose of the displayName property on a React component?

It provides a name shown in React DevTools and error messages, useful for HOCs and anonymous components

displayName is a string property on a component that React DevTools and stack traces use to identify the component. It is especially useful for higher-order components and components created with React.forwardRef or React.memo, which may otherwise show generic names.

88advanced

What is the output of this component on every render?

function App() { const obj = { a: 1 }; const memoObj = useMemo(() => ({ a: 1 }), []); console.log(obj === obj); return null; }
true for the log, but obj is a new object on every render while memoObj is the same reference

obj === obj is trivially true because you are comparing the same variable to itself in one render. However, on each re-render, const obj = { a: 1 } creates a brand new object. memoObj, wrapped in useMemo with [], is the same object reference across all renders.

89advanced

What does React's concurrent mode enable that was not possible before?

Interruptible, pauseable rendering so React can prioritize urgent updates over non-urgent ones

Concurrent mode makes React's rendering work interruptible. React can start rendering, pause if a higher-priority update arrives (like user input), handle that first, then return to the original work. This is the foundation for useTransition and useDeferredValue.

90medium

What is hydration in the context of React server-side rendering?

Attaching React's event listeners and state to HTML that was pre-rendered on the server

Hydration is the process where React takes static HTML sent from the server, builds the virtual DOM from it, and attaches event listeners without re-rendering the DOM. This makes the page interactive while keeping the fast initial load of server-rendered HTML.

91advanced

What does this custom hook return on the second render if the input is the same?

function useStable(value) { return useMemo(() => value, [value]); }
The same reference as the first render if value has the same identity

useMemo uses Object.is to compare dependency values. If value is the exact same reference on the next render, useMemo returns the cached result from the first render. If value is a new object with the same contents, it is a different reference and useMemo recomputes.

92advanced

In a deeply nested component tree, what is the performance drawback of using Context for frequently changing values?

Every component that calls useContext re-renders when the context value changes, even if it only uses a subset of the value

When the context value changes, all components subscribed via useContext re-render, regardless of which part of the value they use. For frequently updating values, splitting context into smaller pieces or using external state managers with selector support is more efficient.

93medium

What is the difference between React.createElement and React.cloneElement?

createElement creates a new element from a type; cloneElement copies an existing element and merges new props into it

React.createElement(type, props, ...children) creates a new element. React.cloneElement(element, extraProps, ...children) takes an existing element, merges extraProps into its existing props, and returns a new element. cloneElement is often used in composition patterns.

94advanced

What is the purpose of the key prop when used outside of a list?

It can force a component to fully unmount and remount when the key changes, resetting its state

Changing the key prop on any element (not just in lists) causes React to unmount the old instance and mount a completely new one. This is a deliberate pattern to reset component state without lifting state or using a useEffect reset.

95advanced

What is the output of this component?

function App() { const [n, setN] = useState(0); useEffect(() => { if (n < 3) setN(n => n + 1); }, [n]); return <p>{n}</p>; }
Shows 3 after a few renders and then stops updating

The effect runs whenever n changes. It increments n until n reaches 3, at which point the if condition is false and setN is not called. React stops re-rendering because n stays at 3, so the effect runs once more with n=3 but does nothing.

96medium

Which hook would you use to synchronously read the previous value of a prop?

A custom hook using useRef to store the previous value in an effect

React has no built-in usePrevious hook. The standard pattern is a custom hook that stores the value in a useRef and updates it after each render via useEffect. On the current render, the ref still holds the value from the previous render.

97advanced

What does the 'use client' directive do in React with the App Router?

It marks a component to be executed on the client side only, enabling hooks and browser APIs

'use client' is a boundary directive in the React Server Components model (used with Next.js App Router). It marks a component and all its imports as client components, enabling the use of hooks, state, effects, and browser APIs.

98advanced

What is wrong with this pattern in a custom hook?

function useData(url) { const [data, setData] = useState(null); useEffect(() => { fetch(url) .then(r => r.json()) .then(setData); }, [url]); return data; }
If the component unmounts before the fetch resolves, setData is called on an unmounted component

If the component unmounts while the fetch is in flight, the .then(setData) call still fires and attempts to update state on an unmounted component. The fix is to use an AbortController or a boolean isMounted flag in the cleanup function.

99advanced

What does React.Children.map differ from Array.prototype.map when used on props.children?

React.Children.map handles cases where children is undefined, null, or a single element without throwing

props.children can be undefined (no children), a single React element (not an array), or an array. Array.prototype.map throws if children is not an array. React.Children.map handles all these cases safely, normalizing children into an iterable first.

100advanced

What is the output of this code when the component first mounts in development with StrictMode?

function App() { const [count, setCount] = useState(() => { console.log('init'); return 0; }); return <p>{count}</p>; }
'init' is logged twice because StrictMode double-invokes state initializers in development

In development mode with StrictMode, React double-invokes the lazy initializer function passed to useState to help detect side effects. You will see 'init' logged twice in the console. In production, it runs only once. The final state value is still 0.