What is React Context?

Key takeaways:

  • React Context allows components to share state directly without prop drilling, improving code clarity and reducing manual prop passing.

  • It is integrated into React and requires no additional dependencies, making it straightforward and efficient for many use cases.

  • Hooks like useContext make it easier to manage the global state across components without prop drilling. This makes it easier to share data like themes or user states across components, streamlining your code and improving maintainability.

  • For apps with simpler state management needs, the React Context offers a cleaner and more straightforward solution than Redux. While Redux is powerful for complex apps, React Context works well when state updates are limited to a few components or involve only a handful of global variables.

React context simplifies state management in React applications by providing a mechanism to share data across components without manually drilling props. Instead of passing data step-by-step, Context allows components to access shared values directly, no matter how deeply nested in the component tree. Unlike traditional state management approaches, React context is lightweight and straightforward for specific use cases like themes, authentication, and localization.

Why use React context?

React context addresses a common problem in React—prop drilling. Prop drilling occurs when data needs to be passed through multiple layers of components, even if only the deeply nested components require it. Context provides a solution by offering direct access to the shared state.

React context
React context

How does React context work?

React Context relies on the Context API introduced in React 16.3. It involves three main steps:

  1. Creating a context using the createContext method. This method creates a Context object and can optionally include a default value:

import { createContext } from 'react';
const CustomThemeContext = createContext("defaultValue");
Creating a context
  1. Using the Provider component to wrap components that need access to the Context. It supplies the data through the value prop.

<CustomThemeContext.Provider value="gray">
<ChangeTheme />
</CustomThemeContext.Provider>
Providing context
  1. Retrieve data using the useContext hook—a simpler way to consume context values, replacing the older Consumer component:

const themeData = useContext(CustomThemeContext);
Consuming context

Learn more React context, by trying this project, Markdown Editor Application in React Using Context APIs and Hooks.

A practical example of React context

Let's build an app with a React context to switch between light and dark themes. The theme value will be managed using React’s useState hook.

Creating and providing context

We will start with creating a context and providing it to a child component in our application.

import React, { createContext, useState } from 'react';
// Create context with a default value
const CustomThemeContext = createContext("light");
function App() {
const [backgroundTheme, setBackgroundTheme] = useState("light");
return (
<CustomThemeContext.Provider value={{backgroundTheme,setBackgroundTheme}}>
<ChangeTheme />
</CustomThemeContext.Provider>
);
}
export default App;
Creating and providing context

Explanation

  • Line 1: We import useState and createContext from React.

  • Line 4: We use createContext to create a new context object, CustomThemeContext. We provide "light" as the default value. If no <Provider> is found above in the component tree, this value will be used when a component consumes the context.

  • Line 7: We declare a state variable called backgroundTheme with an initial value of "light".

  • Line 10: The CustomThemeContext.Provider makes the theme value (backgroundTheme) and the updater function (setBackgroundTheme) available to all child components. The value prop passes these two variables as an object {backgroundTheme,setBackgroundTheme}.

  • Line 12: ChangeTheme is a child component wrapped within the provider, meaning it will have access to the context values.

Consuming context with the useContexthook

Now, let’s create a component that consumes the theme context and allows users to toggle between themes.

import React, { useContext } from 'react';
function ChangeTheme() {
const { backgroundTheme, setBackgroundTheme } = useContext(CustomThemeContext);
function changeTheme() {
setBackgroundTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
};
return (
<button
onClick={changeTheme}
style={{
background: backgroundTheme === "light" ? "#fff" : "#555",
color: backgroundTheme === "light" ? "#000" : "#fff",
}}
>
Switch to {backgroundTheme === "light" ? "Dark" : "Light"} Theme
</button>
);
}
Consuming context with the useContext hook

Explanation

  • Line 4: We use useContext to access the backgroundTheme and setBackgroundTheme values from CustomThemeContext. Now, the ChangeTheme component has access to both the current theme and the function to change it.

  • Lines 6–8: We define a function, changeTheme that checks the current theme, prevTheme. If the theme is "light", it switches it to "dark", and vice versa.

  • Lines 11–19: We render a button with an onClick handler that triggers changeTheme when clicked. The button's style dynamically sets the background color based on the current theme. The button text shows the target theme (e.g., “Switch to Dark Theme” if the current theme is light).

Code example

Let's look at a working example by combining everything and executing the application.

Implement the useContext hook in a real-world application in this project, Build a Location Tracker Using Leaflet, ReactJS, and Express.js.

React context vs. Redux

Apart from React context, we can also Redux to manage the global state of an application or a feature. Redux is a powerful tool for large-scale state management but comes with more boilerplate.

React context and Redux are popular tools for state management in React applications. While both aim to manage shared states effectively, they cater to different levels of complexity and use cases. Let's look at the differences in the table below.

Feature

React context

Redux

Purpose

Manage simple, shared state like themes or user data.

Manage complex, global state with advanced features.

Boilerplate

Minimal setup with the Context API.

Requires significant setup (actions, reducers, store).

Data Flow

Unidirectional, using Provider and useContext.

Unidirectional, using dispatch and reducers.

Performance Optimization

Needs manual memoization of context values.

Built-in mechanisms for optimizing re-renders.

Scalability

Best for small to medium apps.

Suitable for large-scale applications.

Advantages of React context

React context offers several benefits, particularly for smaller-scale applications.

  1. No need to use external libraries, e.g., Redux, reducing dependencies and simplifying project setup.

  2. Context eliminates the need to pass props manually through every component level.

  3. Easy to understand and implement, especially with the useContext hook.

  4. Works seamlessly with React's rendering model without adding significant overhead.

Limitations of React context

Despite its simplicity, React context has some limitations that may affect its suitability for large-scale applications.

  1. Context re-renders all consuming components when the provider’s value changes. This can lead to performance bottlenecks in large trees.

  2. Managing a complex state with Context alone can become cumbersome without middleware or advanced tools.

  3. Debugging deeply nested components relying on multiple contexts can be challenging without specialized tools.

  4. Unlike Redux, React context does not natively support middleware for asynchronous operations or side effects.

Conclusion

React context is a valuable tool for managing the global state in a React application. While it may not replace state management libraries like Redux, its simplicity and integration make it an excellent choice for many use cases. By following best practices and leveraging hooks, you can maximize the potential of React context in your projects.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


When should I use the useContext hook?

Use the useContext hook when there is a need to share states or functions between components without passing them as props. For example, sharing user data or managing themes across components.


How is React Context different from Redux?

Context is simpler and ideal for lightweight state management, while Redux is suited for larger, more complex applications.


Can one component use multiple contexts?

Yes, a single component can use multiple contexts. This is done by simply calling useContext for each context.


Free Resources