What is "derived state"
What is derived state
Derived state is state that can be computed from state or props that already exist.
In simpler terms: it is a duplicate of data that is not the "source of truth", but depends on other data.
Example - derived state in its pure form (bad)
function Example({ items }) {
const [count, setCount] = useState(items.length); // derived state
return <p>Items: {count}</p>;
}Here count fully depends on items.
If items change, count stays old,
until you update it manually via useEffect or setCount.
This creates desynchronization,
you end up with two sources of truth (items and count).
Why derived state is dangerous
1. It violates the "Single Source of Truth" principle
React's architecture is built on the idea:
"Each piece of state should have one source of truth."
When you create derived state, you are effectively making a "copy" of that data. Now you have to make sure both versions always stay in sync. That is a source of bugs.
2. Desynchronized updates
function Example({ items }) {
const [count, setCount] = useState(items.length);
useEffect(() => {
setCount(items.length);
}, [items]);
return <p>{count}</p>;
}Yes, you can "synchronize" it via useEffect,
but that is an extra render and extra complexity.
Why store count if it can be computed directly?
Correct:
function Example({ items }) {
return <p>Items: {items.length}</p>;
}3. Derived data can "lag behind"
If you compute derived state inside setState,
it may use stale data,
since setState is asynchronous:
setItems([...items, newItem]);
setCount(items.length); // still the old valueReact applies both updates later,
and count ends up 1 less than it should be.
What to do instead of derived state
Instead of storing derived data, compute it on the fly when it needs to be rendered.
Example 1 - computing directly in JSX
function Example({ items }) {
const total = items.length; // compute without storing
return <p>Total items: {total}</p>;
}Example 2 - computing inside useMemo (for expensive computations)
If the computation is expensive (for example, filtering, sorting),
use useMemo to cache the result:
function Products({ items, filter }) {
const visibleItems = useMemo(
() => items.filter(item => item.category === filter),
[items, filter]
);
return <p>Shown: {visibleItems.length}</p>;
}Here visibleItems is a derived value,
but not stored state, just a computed value, so it is safe.
When derived state is still acceptable
Sometimes derived state is justified if:
- It is not directly computed from props/state, but holds an intermediate value (for example, the user is typing and we debounce it).
- Or you need to "freeze" a value at the moment of an event.
Examples of acceptable cases:
1. Controlled input (debounce)
const [query, setQuery] = useState("");
const [debouncedQuery, setDebouncedQuery] = useState(query);
useEffect(() => {
const id = setTimeout(() => setDebouncedQuery(query), 500);
return () => clearTimeout(id);
}, [query]);→ debouncedQuery is derived, but deliberately and with an effect.
2. A data "snapshot"
const [snapshot, setSnapshot] = useState(null);
function handleSubmit() {
setSnapshot(formData); // save the form state at submission time
}→ This is not duplication, but capturing a value in time.
Summary
| Question | Answer |
|---|---|
| What is derived state? | State computed from other state or props |
| Why is it bad? | It creates data duplication and desynchronization |
| What's better? | Compute on the fly or via useMemo |
| When is it acceptable? | For data "snapshots", debouncing, intermediate states |
| Main principle | Always keep the "source of truth" in one place |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.