Thanks to visit codestin.com
Credit goes to coreui.io

How to share state between components in React

Sharing state between components in React enables data synchronization and communication across different parts of your application through various state management patterns. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented state sharing patterns in thousands of React applications for dashboard widgets, form management, and component synchronization. From my expertise, the most effective approach is using lifted state for simple cases and Context API for complex shared state scenarios. This method provides clean data flow with proper state encapsulation and efficient re-rendering patterns.

Use lifted state for simple sharing and Context API for complex state that needs to be accessed by multiple components.

import { useState, createContext, useContext } from 'react'

// Method 1: Lifting State Up
function App() {
  const [sharedData, setSharedData] = useState({ count: 0, user: null })

  return (
    <div>
      <Header user={sharedData.user} />
      <Counter
        count={sharedData.count}
        onUpdate={(count) => setSharedData(prev => ({ ...prev, count }))}
      />
      <UserProfile
        user={sharedData.user}
        onUserChange={(user) => setSharedData(prev => ({ ...prev, user }))}
      />
    </div>
  )
}

// Method 2: Context API for Complex State
const AppStateContext = createContext()

function AppStateProvider({ children }) {
  const [state, setState] = useState({
    user: null,
    theme: 'light',
    notifications: []
  })

  const updateUser = (user) => {
    setState(prev => ({ ...prev, user }))
  }

  const addNotification = (notification) => {
    setState(prev => ({
      ...prev,
      notifications: [...prev.notifications, notification]
    }))
  }

  return (
    <AppStateContext.Provider value={{ state, updateUser, addNotification }}>
      {children}
    </AppStateContext.Provider>
  )
}

// Custom hook for consuming context
function useAppState() {
  const context = useContext(AppStateContext)
  if (!context) {
    throw new Error('useAppState must be used within AppStateProvider')
  }
  return context
}

// Using shared state in components
function UserComponent() {
  const { state, updateUser } = useAppState()

  return (
    <div>
      <p>User: {state.user?.name || 'Not logged in'}</p>
      <button onClick={() => updateUser({ name: 'John Doe' })}>
        Login
      </button>
    </div>
  )
}

For simple state sharing between a few components, lift state to the nearest common ancestor and pass data down via props. For complex state accessed by many components, use Context API with custom hooks for clean consumption. This provides efficient re-rendering and clear data flow patterns.

Best Practice Note:

This is the same state sharing architecture we use in CoreUI React components for dashboard state management and component communication across complex interfaces.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to Achieve Perfectly Rounded Corners in CSS
How to Achieve Perfectly Rounded Corners in CSS

JavaScript Operator Precedence and Associativity: A Developer's Complete Guide
JavaScript Operator Precedence and Associativity: A Developer's Complete Guide

How to Conditionally Add a Property to an Object in JavaScript
How to Conditionally Add a Property to an Object in JavaScript

How to round a number to two decimal places in JavaScript
How to round a number to two decimal places in JavaScript

Answers by CoreUI Core Team