Sitemap

How React Context works under the hood

3 min readMay 24, 2025

--

What is React Context?

React Context is a built-in feature that lets you share values (state, functions, etc.) across the entire component tree without passing props manually at every level.

It’s often used for things like:

  • Theme (dark/light)
  • Auth user data
  • Language or locale
  • Toggle states, config settings

Under the Hook: How React Context Works

At a high level:

  1. You create a context object
  2. You wrap your component tree with a Provider and pass it a value
  3. Any descendant component can “consume” that value via useContext
  4. Wrap Your App with the context

Think of it like a global container of state available to all child components within a certain scope.

Let’s Build It Step-by-Step

Step 1: Create a Context

import React, { createContext, useState } from 'react';

// Create the context (a container)
const ThemeContext = createContext();

What happens here:

ThemeContext is an object with two components:

  • ThemeContext.Provider: where you define the value
  • ThemeContext.Consumer: an older way to read the value

Step 2: Create a Provider Component

This is the “source of truth” that stores the data and shares it.

export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
const toggleTheme = () =>
setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};

What happens under the hood:

  • When the value ({ theme, toggleTheme }) changes, all children using this context re-render automatically.
  • React keeps a reference to that value and tracks which children are listening for changes.

Step 3: Use Context in Children

import React, { useContext } from 'react';
import { ThemeContext } from './theme-context';

const Header = () => {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<header style={{ background: theme === 'light' ? '#fff' : '#333' }}>
<p>Current theme: {theme}</p>
<button onClick={toggleTheme}>Toggle Theme</button>
</header>
);
};

What does useContext really do?

When you call useContext(SomeContext), React:

  1. Walks up the component tree to find the nearest matching <SomeContext.Provider>
  2. Reads its value
  3. Subscribes your component to that context’s updates
  4. Re-renders your component only if the context value changes

React uses reference equality to detect value changes. So if the value is a new object or function, components will re-render.

Step 4: Wrap Your App

import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider } from './theme-context';
import App from './App';

ReactDOM.render(
<ThemeProvider>
<App />
</ThemeProvider>,
document.getElementById('root')
);

Here’s what React Context API really does behind the scenes:

// Pseudocode of how React context might be implemented

const MyContext = React.createContext(defaultValue);

// Somewhere in your tree
<MyContext.Provider value={someValue}>
<Child />
</MyContext.Provider>

// React stores the value in an internal fiber field
// Then inside a component that does:
const value = useContext(MyContext);

// React walks up the fiber tree to find the nearest Provider
// When the value changes, it re-renders all the consuming components

Common Gotchas

  1. Context Re-renders Everything Using It
  • Even if one value inside value={{ a, b }} changes, all components using the context re-render
  • Solution: Split context or memoize the value using useMemo
const value = useMemo(() => ({ theme, toggleTheme }), [theme]);

2. Don’t Use for High-Frequency Updates

  • Avoid using context for things like animation frame updates or mouse position — it’s not performant
  • Use local state or other tools like Zustand or Redux

Summary

  • createContext() Creates a shared state container
  • Provider Supplies the context value to children
  • useContext() Lets you access that value in any child.
  • Under the hood React uses internal fiber links + subscriptions
  • Optimize with useMemo Prevents re-renders on shallow value change.

--

--

Ly Channa
Ly Channa

Written by Ly Channa

Highly skilled: REST API, OAuth2, OpenIDConnect, SSO, TDD, RubyOnRails, CI/CD, Infrastruct as Code, AWS.

No responses yet