Skip to main content

What does "state colocation" do?

What is state colocation

State colocation is the principle:

"Keep state as close as possible to where it is used."

That is: if state is needed only by one component - do not lift it "up" to the parent, but keep it right in the component where it is actually used.


Example without colocation (bad)

javascript
function App() { const [isOpen, setIsOpen] = useState(false); // stored too high up return ( <div> <Header /> <Modal isOpen={isOpen} setIsOpen={setIsOpen} /> <Footer /> </div> ); }

Here isOpen affects only Modal, but it is stored in App and passed down through props.

→ This complicates the App component, and causes unnecessary re-renders when the state changes.


With colocation (correct)

javascript
function Modal() { const [isOpen, setIsOpen] = useState(false); return ( <> <button onClick={() => setIsOpen(true)}>Open</button> {isOpen && <div className="modal">Modal!</div>} </> ); }

Now the state lives where it is actually used. The App component no longer knows anything about Modal's internal logic.


Why this matters

1. Less coupling

When state lives "up top", it starts to:

  • get passed through props across several levels,
  • cause "prop drilling" (passing props through a chain of components),
  • complicate the parent's logic.

Colocation removes this - each component is responsible only for itself.


2. Fewer unnecessary re-renders

If state is stored too high up, all child components re-render, even if they do not depend on it.

When state is localized, only the component that needs it reacts to the update.

This improves performance.


3. The code is easier to understand

A component is easier to read when:

  • its state is visible in the same file,
  • it is visible which UI elements that state controls.

You do not need to jump between files to understand who manages what.


4. Easier to scale

As a project grows, "global" state turns into chaos. Colocation makes the architecture modular:

  • components can be reused independently,
  • state does not "leak" outward.

Example of the impact on performance

Without colocation

javascript
function App() { const [selectedId, setSelectedId] = useState(null); return ( <div> <List selectedId={selectedId} setSelectedId={setSelectedId} /> <Details id={selectedId} /> </div> ); }

Now every click in the list → re-render of App, List, and Details.

With colocation (partially moved down)

javascript
function List({ onSelect }) { const [selectedId, setSelectedId] = useState(null); const handleClick = (id) => { setSelectedId(id); onSelect(id); }; // ... }

Now a click only updates List, and App is not touched at all.


When you do not need to localize state

Sometimes the opposite is true - state needs to be lifted up, if:

  • it affects several components (shared state);
  • synchronization between parts of the UI is required;
  • or global management is needed (via Context, Redux, Zustand, etc.).

Example:

javascript
// the selected theme is needed by all components const [theme, setTheme] = useState("dark");

Summary

PrincipleWhat it means
State colocationKeep state as close as possible to where it is used
WhyReduces coupling, improves performance, simplifies the code
When to applyWhen state is used in only one component
When not to applyWhen state needs to be shared between several components
Main goalMinimize the state's "area of influence"

Short Answer

Interview ready
Premium

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