Lesson 18 of 80
The single highest-leverage React habit: if a value can be computed from state you already have, it isn't state — computing it during render beats syncing it with an effect, every time.
13 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
What's the test for whether a value should be its own useState, versus computed during render?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Derived state is a value that can be calculated from other state or props. The mistake is storing it as its own useState and then writing an effect to keep it "in sync":
// 🐛 unnecessary state + effect
function Cart({ items }) {
const [total, setTotal] = useState(0);
useEffect(() => {
setTotal(items.reduce((sum, i) => sum + i.price, 0));
}, [items]);
return <p>{total}</p>;
}
// ✅ just compute it during render
function Cart({ items }) {
const total = items.reduce((sum, i) => sum + i.price, 0);
return <p>{total}</p>;
}
The first version has a real bug hiding in it: after items changes, there's a render where total is still the old value (state hasn't caught up yet), followed by an effect firing, followed by a second render with the correct value. The second version is simply always correct, has no extra render, and has no state to keep in sync in the first place.
useState for items, then ANOTHER useState for total kept in sync via useEffect — two sources of truth that can drift.
State colocation is the related habit of keeping state in the lowest (most specific) component that needs it, rather than lifting everything to a shared ancestor "just in case." A search box's isFocused flag belongs in the search box, not in the page-level state — lifting it up only means more of the page re-renders on every keystroke, for no benefit.
useEffect is very likely the wrong tool."Why would you avoid using useEffect to sync one piece of state with another?" is a question that separates candidates who've only used hooks from ones who've internalized React's actual mental model — computing during render, not syncing after the fact.