HomeAbout Me

React Hooks: Lifting State

By Daniel Nguyen
Published in React JS
June 04, 2025
2 min read
React Hooks: Lifting State

🪄 Mastering State Management in React: Lifting and Colocating State

React makes it easy to build dynamic user interfaces by managing UI state. But what happens when multiple components need to share or manage that state? In this blog post, we’ll walk through one of the most important concepts in React development: lifting and colocating state.

We’ll break this into three core parts:

  1. Lifting State – Sharing state across sibling components.
  2. Lifting More State – Centralizing state for global behavior.
  3. Colocating State – Pushing state back down for maintainability and performance.

Let’s dive in! 🏊‍♂️


🎈 Part 1: Lifting State — Sharing Data Between Siblings

A common challenge for beginners is: “How do I share state between sibling components?”

The answer: Lift the State Up

You move the state to the closest common parent and pass it down via props.

Let’s start with a simple example:

import { useState } from 'react'
function App() {
return (
<div>
<Counter />
</div>
)
}
function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}

Now let’s add a sibling component:

function App() {
return (
<div>
<Counter />
<CountDisplay />
</div>
)
}
function CountDisplay() {
return <div>Count: 0</div>
}

Right now, CountDisplay doesn’t know the actual count. To fix this, we lift the state to the App component:

function App() {
const [count, setCount] = useState(0)
return (
<div>
<Counter count={count} setCount={setCount} />
<CountDisplay count={count} />
</div>
)
}
function Counter({ count, setCount }) {
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}
function CountDisplay({ count }) {
return <div>Count: {count}</div>
}

Now both components are synced through shared state. This pattern of lifting state is extremely common and essential to understanding React’s unidirectional data flow.


🧠 Part 2: Lifting More State — For Shared Features

Imagine we now have a blog app where each post can be “liked” with a heart ❤️. Initially, you may have implemented the like functionality inside each Card component, using local state.

function Card({ post }) {
const [liked, setLiked] = useState(false)
return (
<div>
<h2>{post.title}</h2>
<button onClick={() => setLiked(!liked)}>
{liked ? '💖' : '🖤'}
</button>
</div>
)
}

But now the product team wants a new feature:

“Sort posts based on whether they’re liked.”

To achieve this, we need a global understanding of which posts are liked — that means we have to lift the liked state up to a parent, such as the MatchingPosts component.

This involves:

  • Managing all liked post IDs in the parent component.
  • Passing the liked status and toggle function down as props to each card.

Once lifted, we can easily sort the posts and re-render based on their liked status.

Key takeaway: Lift state when multiple components depend on the same piece of data or when global behavior (like sorting) is needed.


⚖️ Part 3: Colocating State — Pushing It Back Down

After implementing and releasing the feature to sort posts by likes, users report:

“It’s confusing to have posts reorder themselves when I like something.”

So the product team decides to remove the sorting functionality. Now, no other component needs to know which posts are liked.

Does that mean the lifted state is still useful?

🛑 Nope. It’s time to colocate.

Since the liked state is now only needed inside the Card component, we should move it back into that component to improve:

  • Performance (fewer re-renders of the parent)
  • Maintainability (simpler prop chains)

Reverting back to this is ideal:

function Card({ post }) {
const [liked, setLiked] = useState(false)
return (
<div>
<h2>{post.title}</h2>
<button onClick={() => setLiked(!liked)}>
{liked ? '💖' : '🖤'}
</button>
</div>
)
}

Key takeaway: Colocate state whenever possible. Don’t keep it higher in the component tree than it needs to be.

🧪 Pro tip: Always evaluate who uses the state. If it’s just one component — keep it there.


💡 Final Thoughts

React gives you flexibility in how you structure and manage your state. Learning when to lift and when to colocate is a hallmark of progressing from junior to senior React developer.

Here’s a summary:

ScenarioAction
Multiple components need shared dataLift the state
Component needs isolated stateColocate the state
Global behavior like sorting/filteringLift the state
State is no longer sharedColocate it again

📚 Further Reading


👨‍🏫 Practice what you’ve learned: Next time you’re building a feature, ask yourself:

“Who actually needs this piece of state?”

Then decide whether to lift or colocate based on that answer.

Happy coding! 🚀


Tags

#ReactHooks

Share

Previous Article
React Hooks: Side-Effects

Table Of Contents

1
🎈 Part 1: Lifting State — Sharing Data Between Siblings
2
🧠 Part 2: Lifting More State — For Shared Features
3
⚖️ Part 3: Colocating State — Pushing It Back Down
4
💡 Final Thoughts
5
📚 Further Reading

Related Posts

React Hook: Tic Tac Toe
June 07, 2025
2 min
© 2025, All Rights Reserved.
Powered By

Quick Links

About Me

Legal Stuff

Social Media