Notify the parent in the handler, not in an effect
The effect version needs two render passes: the toggle renders, its effect tells the parent, then everything renders again. The event version updates both states in one handler, and React batches them into a single pass.
If no outside system is involved, you usually don't need an effect: calculate derived data during render (with useMemo if it's slow), reset state with a key, put user-caused logic in event handlers, and run app-wide setup once at module level.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Remove the effect:
``jsx
function Cart({ items }) {
const [total, setTotal] = useState(0);
useEffect(() => {
setTotal(items.reduce((s, i) => s + i.price, 0));
}, [items]);
return <p>Total: {total}</p>;
}
A <ChatThread threadId={id} /> keeps a draft and a scrollTop in state, and both must reset when the thread changes. Show the fix in the parent.
Explain it without notes
Why is storing derived data in state and updating it with an effect a mistake?
How do you reset all of a component's state when a prop changes, without an effect?
A child calls onChange from an effect when its state changes. What's wrong, and what's the fix?
Where should code go that must run exactly once when the app loads?
Preview
Console
Nothing logged yet.Expected console output
App render | a: false b: false
effect toggle render, on: false
event toggle render, on: false
--- click the effect toggle
effect toggle render, on: true
App render | a: true b: false
effect toggle render, on: true
event toggle render, on: false
--- click the event toggle
App render | a: true b: true
effect toggle render, on: true
event toggle render, on: true