4.8 use one state has the place and what is bette
In the previous lesson we called setUserInput by passing the next state object directly. This works most of the time, but it is not safe when the next state actually depends on the previous one — which is exactly our case, because we spread userInput back into itself. The recommended pattern in React is to pass a function to the setter instead of a plain object.
Comment out the previous version of setUserInput and rewrite it so that its argument is an arrow function. That arrow function receives the most recent state snapshot as a parameter — we conventionally call it prevState — and must return the new state object.
const titleChangeHandler = (event) => {
setUserInput((prevState) => {
return { ...prevState, enteredTitle: event.target.value };
});
};
Why the function form is safer
- React guarantees that
prevStateis the latest state snapshot, even when several updates are queued together. - You no longer rely on
userInputfrom the surrounding closure, which could be stale. - This pattern is exactly the same idea you used with
setCount(prev => prev + 1)in basic counters.
The same wrapper applies to amountChangeHandler and dateChangeHandler: change the key after the spread to enteredAmount or enteredDate as needed. Keep this technique in mind in general: whenever the next state depends on the previous one — especially when merging objects like we do here — prefer the function form of the setter. With that said, in the next lesson we will actually go back to the multi-state approach with three separate useState calls, because it is often clearer in real-world forms.
Summary
This lesson explores React state management patterns, specifically how to use setState with a callback function that receives the previous state. It demonstrates using the spread operator to merge and update state objects, and explains when consolidating multiple state properties into a single state object is appropriate versus keeping them separate. The key pattern shown is passing a function to the state setter that receives the previous state snapshot, allowing safe updates that depend on the current state value.
Key points
- Use setState with a callback function to access the previous state snapshot via the prevState parameter
- Apply the spread operator (...) to merge old and new state properties when consolidating state
- This pattern is essential when your state update depends on the previous state value
- Event handlers like onChange can be paired with this pattern to efficiently update merged state objects
- Consider consolidating related state properties into a single object when they are frequently updated together
- Keep state separate only when properties truly have no logical relationship
FAQ
When should I pass a function instead of a value directly to setState?
You should pass a function when your new state depends on the previous state value. This ensures React passes you the most current state snapshot before your update is applied, preventing race conditions and stale state issues.
What is the purpose of the spread operator (...) in state updates?
The spread operator allows you to merge the previous state with new properties in a single object. For example, {...prevState, title: newValue} preserves all existing properties while updating only the title field.
Should I consolidate all state into one object or keep properties separate?
Consolidate related state properties that are frequently updated together or have logical dependencies. Keep unrelated properties separate to avoid unnecessary re-renders and make your component logic clearer.