0
0
Reactframework~15 mins

Sharing state between components in React - Deep Dive

Choose your learning style9 modes available
Overview - Sharing state between components
What is it?
Sharing state between components means making data available to more than one part of a React app so they can work together smoothly. Instead of each component having its own separate data, they can use shared information to stay in sync. This helps build apps where different parts react to changes in the same data instantly.
Why it matters
Without shared state, components would not know about each other's changes, causing inconsistent displays and confusing user experiences. Imagine a shopping cart where the item count updates in one place but not another. Sharing state solves this by keeping all parts updated, making apps feel fast and reliable.
Where it fits
Before learning this, you should understand React components and how state works inside a single component. After this, you can learn about advanced state management libraries like Redux or Zustand, and how to optimize performance when many components share state.
Mental Model
Core Idea
Sharing state means lifting data up to a common parent or using a shared store so multiple components can read and update the same information together.
Think of it like...
It's like a family sharing a single calendar on the fridge. Everyone can see and add events, so no one misses important dates or double-books plans.
┌───────────────┐       ┌───────────────┐
│ Component A   │       │ Component B   │
│ (needs state) │       │ (needs state) │
└──────┬────────┘       └──────┬────────┘
       │                       │
       │                       │
       ▼                       ▼
  ┌───────────────────────────────┐
  │      Shared State Holder       │
  │ (Parent or Context Provider)   │
  └───────────────────────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding component state basics
🤔
Concept: Learn what state is inside a React component and how it controls what the component shows.
In React, each component can have its own state using the useState hook. This state holds data that can change over time, like a counter number or text input. When state changes, React updates the component's display automatically.
Result
You can create interactive components that remember and show changing data.
Understanding local state is the first step to knowing why and how to share state between components.
2
FoundationProps: passing data down components
🤔
Concept: Learn how to send data from a parent component to its children using props.
Props are like function arguments for components. A parent component can pass data to its child by adding attributes. The child reads these props but cannot change them directly.
Result
Child components can display or use data given by their parent.
Props let components communicate downward, but they don't allow sharing state changes upward or sideways.
3
IntermediateLifting state up to share data
🤔Before reading on: do you think child components can directly change their parent's state? Commit to yes or no.
Concept: Learn how to move state to the closest common parent so multiple children can access and update it.
If two sibling components need the same data, you move the state to their parent. The parent holds the state and passes it down as props. It also passes functions to update the state. Children call these functions to change the shared data.
Result
Multiple components stay in sync by reading and updating the same state from their parent.
Lifting state up creates a single source of truth, preventing data mismatches between components.
4
IntermediateUsing React Context for global state
🤔Before reading on: do you think React Context replaces all state management needs? Commit to yes or no.
Concept: Learn how React Context lets you share state deeply without passing props through many layers.
React Context creates a shared data store accessible by any component inside its provider. You create a context, wrap components with its provider, and use useContext hook to read or update the shared state anywhere inside.
Result
Components can share state without prop drilling, making code cleaner and easier to maintain.
Context is great for global or app-wide state but can cause unnecessary re-renders if not used carefully.
5
AdvancedAvoiding performance pitfalls in shared state
🤔Before reading on: do you think updating shared state always updates every component using it? Commit to yes or no.
Concept: Learn how shared state updates can cause many components to re-render and how to optimize this.
When shared state changes, React re-renders all components that use it. This can slow down apps if many components update unnecessarily. Techniques like memoization, splitting context, or using selectors help limit re-renders to only components that need updates.
Result
Apps stay fast and responsive even with complex shared state.
Knowing how React decides what to re-render helps you design shared state for better performance.
6
ExpertCustom hooks for reusable shared state logic
🤔Before reading on: do you think shared state logic belongs only in components? Commit to yes or no.
Concept: Learn how to extract shared state logic into custom hooks for reuse and cleaner code.
Custom hooks are functions that use React hooks inside and return state and updater functions. You can create a custom hook that manages shared state and use it in multiple components. This keeps state logic in one place and components simpler.
Result
You build scalable, maintainable apps with shared state logic neatly organized.
Custom hooks separate concerns and make shared state easier to test and reuse across components.
Under the Hood
React keeps a virtual tree of components and their states. When shared state changes, React schedules updates and re-renders components that depend on that state. Context uses React's internal subscription system to notify components when the shared value changes. React batches updates to minimize work and uses reconciliation to update only changed parts of the UI.
Why designed this way?
React was designed to keep UI in sync with data declaratively. Sharing state through lifting or context fits this by centralizing data and letting React handle updates efficiently. Alternatives like global variables or manual DOM updates were error-prone and hard to maintain.
┌───────────────┐
│ Shared State   │
│ (useState or  │
│  Context)     │
└──────┬────────┘
       │ updates
       ▼
┌───────────────┐
│ React Scheduler│
│ batches and   │
│ queues renders│
└──────┬────────┘
       │ triggers
       ▼
┌───────────────┐
│ Components    │
│ re-render with│
│ new state     │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Can sibling components directly share state without a parent? Commit yes or no.
Common Belief:Siblings can share state directly by accessing each other's state variables.
Tap to reveal reality
Reality:Siblings cannot directly access each other's state; state must be lifted to a common parent or shared via context.
Why it matters:Trying to share state directly causes bugs and forces complex workarounds, making code fragile.
Quick: Does React Context automatically optimize re-renders? Commit yes or no.
Common Belief:Using React Context means only components that use changed data will re-render.
Tap to reveal reality
Reality:Any component consuming context re-renders whenever the context value changes, even if it doesn't use the changed part.
Why it matters:Ignoring this leads to performance issues in large apps with frequent context updates.
Quick: Is lifting state up always the best way to share state? Commit yes or no.
Common Belief:Lifting state up is always the best and simplest way to share state between components.
Tap to reveal reality
Reality:Lifting state up works well for small trees but becomes cumbersome with deep or many components; context or state libraries may be better.
Why it matters:Overusing lifting leads to 'prop drilling' and hard-to-maintain code.
Quick: Can you mutate shared state directly in React? Commit yes or no.
Common Belief:You can change shared state objects directly to update components faster.
Tap to reveal reality
Reality:React requires state to be treated as immutable; direct mutation prevents React from detecting changes and updating UI.
Why it matters:Mutating state causes UI bugs where components don't update as expected.
Expert Zone
1
Using multiple smaller contexts instead of one big context reduces unnecessary re-renders and improves performance.
2
Custom hooks can encapsulate complex shared state logic with side effects, making components cleaner and easier to test.
3
React's concurrent mode changes how state updates are scheduled, affecting shared state behavior and requiring careful design.
When NOT to use
Sharing state via lifting or context is not ideal for very large or complex apps with many unrelated state pieces. In such cases, dedicated state management libraries like Redux, MobX, or Zustand provide better scalability, middleware support, and debugging tools.
Production Patterns
In real apps, shared state is often split: local state for UI details, context for theme or user info, and external libraries for complex data. Patterns like 'state colocation' keep state close to where it's used, and 'selector hooks' optimize component updates.
Connections
Observer Pattern
Shared state with React Context follows the observer pattern where components subscribe to state changes.
Understanding observer pattern clarifies how React notifies components about shared state updates.
Database Transactions
Both shared state and database transactions manage consistent data across multiple users or components.
Knowing how databases ensure data consistency helps grasp why React centralizes state to avoid conflicting UI views.
Human Team Collaboration
Sharing state in React is like team members sharing a common plan to coordinate actions.
Seeing shared state as team communication highlights the importance of a single source of truth for smooth cooperation.
Common Pitfalls
#1Passing state down many layers causes messy code and hard maintenance.
Wrong approach:function GreatGrandparent() { const [count, setCount] = React.useState(0); return ; } function Grandparent(props) { return ; } function Parent(props) { return ; } function Child(props) { return ; }
Correct approach:const CountContext = React.createContext(); function GreatGrandparent() { const [count, setCount] = React.useState(0); return ; } function Child() { const {count, setCount} = React.useContext(CountContext); return ; }
Root cause:Not using context leads to 'prop drilling' where props pass through components that don't need them.
#2Mutating shared state object directly causes UI not to update.
Wrong approach:const [user, setUser] = React.useState({name: 'Alice'}); user.name = 'Bob'; setUser(user);
Correct approach:const [user, setUser] = React.useState({name: 'Alice'}); setUser({...user, name: 'Bob'});
Root cause:React detects state changes by reference; mutating the same object does not trigger updates.
#3Using one big context for all state causes slow app performance.
Wrong approach:const AppContext = React.createContext(); function App() { const [state, setState] = React.useState({user: {}, theme: {}, cart: []}); return {children}; } // All components consume AppContext and re-render on any change
Correct approach:const UserContext = React.createContext(); const ThemeContext = React.createContext(); const CartContext = React.createContext(); // Provide and consume contexts separately to limit re-renders
Root cause:Large context values cause all consumers to re-render even if they use unrelated parts.
Key Takeaways
Sharing state means moving data to a place where multiple components can access and update it together.
Lifting state up to a common parent or using React Context are the main ways to share state between components.
React Context helps avoid passing props through many layers but can cause performance issues if not split carefully.
Always treat state as immutable to ensure React detects changes and updates the UI correctly.
Advanced patterns like custom hooks and splitting contexts help build scalable and maintainable shared state.