Skip to main content

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

javascript
{ user: { profile: { name: "Tim", age: 25 }, settings: { theme: "dark" } } }

it is better to store the state flat:

javascript
{ userName: "Tim", userAge: 25, userTheme: "dark" }

or, if you need to store related data, use separate pieces of state:

javascript
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:

javascript
const [user, setUser] = useState({ name: "Alex", address: { city: "Paris", zip: "75000" }, });

To update the city:

javascript
// 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:

javascript
const [state, setState] = useState({ user: { name: "Tim" }, theme: "dark" });

And you update only theme:

javascript
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

BenefitWhy it matters
Easier to updateNo need to copy several levels
Fewer bugsLower risk of breaking immutability
Faster renderingLocal updates do not touch the whole tree
Easier to testYou can isolate the update logic of each part
Easier to reason aboutState becomes declarative and transparent

Example: "deep" vs "flat"

Deep state:

javascript
const [state, setState] = useState({ user: { name: "Tim", age: 25 }, settings: { theme: "dark", notifications: true }, });

Updating the theme:

javascript
setState(prev => ({ ...prev, settings: { ...prev.settings, theme: "light" }, }));

Flat state:

javascript
const [user, setUser] = useState({ name: "Tim", age: 25 }); const [theme, setTheme] = useState("dark"); const [notifications, setNotifications] = useState(true);

Updating the theme:

javascript
setTheme("light");

Simple, clear, safe.


When nested structures are still fine

Sometimes nesting makes sense:

  • when working with logically cohesive data (for example, user or address);
  • 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

QuestionAnswer
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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.