In a React class component, what is static getDerivedStateFromProps(props, state) called with, when does it run, and what is the function-component equivalent?
answer
- static means no this, no previous props
- not 'when props change'
- returns partial state or null
- mirror the prop to compare it
- no hook mirrors it, and that is deliberate
basics
~20 sIt is a static method receiving the next props and current state, called before every render — on mount and on every update, whatever triggered it. It returns an object merged into state, or null. Function components have no direct equivalent: derive during render instead.
solid answer
~50 s`static getDerivedStateFromProps(props, state)` is static, so it has no `this` — no instance, no previous props, no access to other methods. React calls it immediately before every render, both on the initial mount and on every subsequent update, regardless of whether props actually changed; a re-render caused purely by the component's own `setState` calls it too. It returns an object that is shallow-merged into state, or `null` to change nothing. Because it cannot see previous props, comparing them means mirroring the prop into state and comparing against that copy, which is where most of its bugs come from. There is no hook that mirrors it, and that is intentional: nearly every real use is either a value you should compute during render rather than store, or a reset that is better expressed by giving the component a different `key`. The narrow remaining case — adjusting state during render while remembering the previous prop — React supports directly by calling a setter during rendering.
code
jsx · 14 linesimport { useState } from 'react';
export function EditableName({ initialName }) {
const [name, setName] = useState(initialName);
const [prevInitial, setPrevInitial] = useState(initialName);
// Adjusting state during render: the hook-era stand-in for gDSFP.
if (initialName !== prevInitial) {
setPrevInitial(initialName);
setName(initialName);
}
return <input value={name} onChange={(e) => setName(e.target.value)} />;
}go deeper
Know that it is a static method returning a partial state object or null, that React calls it before rendering, and that copying props into state is a pattern to be suspicious of.
Explain that it runs before every render regardless of what caused the update, that being static means no access to previous props, and that comparing props therefore requires mirroring the prop in state.
Diagnose the field that resets itself when an unrelated sibling updates, and argue for removing the derived state entirely — compute during render, or reset the component by changing its key.
Own the rule that a single source of truth beats synchronization. Duplicating props into state is the root cause the API keeps producing, and a codebase standard against it removes a whole family of bugs rather than one instance.
## The signature and the call schedule ```jsx class Form extends React.Component { state = { value: '', prevDefault: null }; static getDerivedStateFromProps(props, state) { if (props.defaultValue !== state.prevDefault) { return { value: props.defaultValue, prevDefault: props.defaultValue }; } return null; } } ``` Three facts do most of the work in an interview: 1. **It is static.** No `this`, so no `this.props` (the previous props), no instance methods, no refs. React deliberately removed that access so the method stays pure. 2. **It runs before every render.** Initial mount included, and every update included — even an update caused only by the component calling its own `setState`. It is not "when props change"; nothing tells it that props changed. 3. **Its return value is shallow-merged into state**, exactly like an object passed to `setState`. Returning `null` means "no change", and it must return a state object or `null` — returning nothing is a mistake React warns about. ## Why it is so often wrong The method's most common use is copying a prop into state so the component can then edit it locally. That immediately raises the question every update has to answer: has the prop changed since last time, or has the user edited the local copy? Because the method cannot see previous props, the only way to answer it is to keep a mirror of the prop *inside state* and compare against that — the `prevDefault` field above. Get that wrong and you get one of two classic bugs. Compare `props.defaultValue` against `state.value` instead of against a stored mirror, and every keystroke that happens to type the original value snaps the field back. Omit the comparison entirely and the field resets on every parent re-render, wiping the user's typing whenever an unrelated sibling updates. The deeper problem is duplication: the value now lives in two places, and every render has to reconcile them. ## The function-component story There is no `useDerivedStateFromProps`, and asking for one is usually the wrong question. In order of preference: **Compute it during render.** If the value is a function of props and state, calculate it in the component body. Nothing to synchronize, nothing to get stale. **Reset by identity.** If the intent is "when this prop changes, start over", giving the component a different `key` makes React discard the old instance and mount a fresh one with fresh state. That expresses the intent directly. **Adjust state during render.** For the genuinely narrow case — you must keep local editable state *and* reset part of it when a prop changes — React supports calling a setter during rendering, provided you guard it with a stored previous value: ```jsx function Form({ defaultValue }) { const [value, setValue] = useState(defaultValue); const [prevDefault, setPrevDefault] = useState(defaultValue); if (defaultValue !== prevDefault) { setPrevDefault(defaultValue); setValue(defaultValue); } return <input value={value} onChange={(e) => setValue(e.target.value)} />; } ``` React notices the update during render, discards the output it was building and re-runs the component immediately, before touching the DOM and without rendering children twice. It is the same shape as `getDerivedStateFromProps` — including the stored previous prop — but it is ordinary code you can read top to bottom. Note that this only works when the setter targets the component that is currently rendering; calling another component's setter during render is an error. ## The interview shape Give the signature and the schedule crisply (static, before every render, mount and update alike, returns partial state or `null`), then say why it exists at all: it replaced `componentWillReceiveProps` and was made static specifically to stop people running side effects during the render phase. Finish with the honest modern position — most uses were prop-to-state duplication that should be a derived value or a `key` change instead.
- Why did React make getDerivedStateFromProps static rather than an instance method?To make it structurally pure. Without `this`, it cannot read previous props, touch refs, call instance methods or fire side effects — it can only map incoming props and current state to a state patch. That was the whole point of replacing componentWillReceiveProps, which ran in the render phase and was routinely used for subscriptions and fetches.
- Does getDerivedStateFromProps run when the component updates because of its own setState, with no new props?Yes. React calls it before every render regardless of cause, so a purely internal state update still runs it with the same props as before. Code written as if it only fires on prop changes will re-apply its patch on every internal update, which is exactly how the 'my input keeps resetting itself' bug appears.
- Is calling a setState function during render not a violation of purity?React allows this one narrow pattern: a component updating its own state during its own render, guarded so it cannot loop. React throws away the in-progress output and re-runs the component before committing anything, so no DOM is touched and children are not rendered twice. Calling another component's setter during render is still an error.
saying these in an interview costs you the question
- It only runs when props actually change
- You can read this.props inside it to compare previous props
- Returning undefined is the same as returning null
- It is the natural place to fetch data when a prop changes
- useEffect that copies a prop into state is the hook equivalent