Flat state (flat state)
What "flat state" means
Flat state is when the data in useState (or useReducer)
is not deeply nested inside objects,
but is stored "at a single level".
Example: instead of a bulky structure
{
user: {
profile: {
name: "Tim",
age: 25
},
settings: {
theme: "dark"
}
}
}it is better to store the state flat:
{
userName: "Tim",
userAge: 25,
userTheme: "dark"
}or, if you need to store related data, use separate pieces of state:
const [profile, setProfile] = useState({ name: "Tim", age: 25 });
const [theme, setTheme] = useState("dark");Why React likes "flat" state
React re-renders a component every time state updates, and it matters that updates stay local and simple.
Deeply nested structures break that simplicity.
Problem 1: nested data is hard to update
An example of "nested" state:
const [user, setUser] = useState({
name: "Alex",
address: { city: "Paris", zip: "75000" },
});To update the city:
// you have to copy every level manually
setUser(prev => ({
...prev,
address: { ...prev.address, city: "Lyon" },
}));The deeper the object, the more boilerplate code and the higher the chance of a mistake.
And if you forget to make the copy (...prev.address),
React will not notice the change (immutability breaks).
Problem 2: harder to memoize and optimize
If you have complex state, for example:
const [state, setState] = useState({
user: { name: "Tim" },
theme: "dark"
});And you update only theme:
setState(prev => ({ ...prev, theme: "light" }));React still creates a new state object,
and all of its properties get new references.
Components that depend only on user
will also re-render, even though user did not change.
Loss of performance and predictability.
Problem 3: partial updates are hard
React does not "merge" objects automatically (unlike class components with this.setState).
So you always have to manually copy the entire nested path.
Flat state solves this: you update only the part you need, without extra nesting.
Benefits of flat state
| Benefit | Why it matters |
|---|---|
| Easier to update | No need to copy several levels |
| Fewer bugs | Lower risk of breaking immutability |
| Faster rendering | Local updates do not touch the whole tree |
| Easier to test | You can isolate the update logic of each part |
| Easier to reason about | State becomes declarative and transparent |
Example: "deep" vs "flat"
Deep state:
const [state, setState] = useState({
user: { name: "Tim", age: 25 },
settings: { theme: "dark", notifications: true },
});Updating the theme:
setState(prev => ({
...prev,
settings: { ...prev.settings, theme: "light" },
}));Flat state:
const [user, setUser] = useState({ name: "Tim", age: 25 });
const [theme, setTheme] = useState("dark");
const [notifications, setNotifications] = useState(true);Updating the theme:
setTheme("light");Simple, clear, safe.
When nested structures are still fine
Sometimes nesting makes sense:
- when working with logically cohesive data (for example,
useroraddress); - when using useReducer (it lets you update complex structures through a reducer);
- when the state needs to be passed as a "bundle".
But even then, try to keep the structure shallow (1-2 levels at most).
Summary
| Question | Answer |
|---|---|
| What does "flat state" mean? | Minimal nesting, each value stored separately |
| Why does React want this? | It makes updating, comparing and optimizing easier |
| What is wrong with nested objects? | Hard to update and copy, higher risk of bugs |
| When is nesting acceptable? | In limited cases, if the data is logically related |
| Ideal principle | "State should be as simple as possible, but not simpler." |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.