React Context: The fundamentals you must know

Daminda Dinesh Imaduwa Gamage
6 min readJul 7, 2023
React Context
Photo by Lautaro Andreani on Unsplash

In this post, I am going to help you understand the fundamental concepts of React Context. We will discuss the main components that you need to create and use React Context. We are also going to see the use cases of React Context, compare its advantages with disadvantages, and, finally see when to use React Context and when to avoid it.

Why React Context

Data flow in React applications is unidirectional, which means data passes from parent components to child components. These data pass via props ( Properties ) from the parent component to the child component.

This parent, child, and prop system works fine with small applications. However, as the application gets larger, it can have nested child components creating a tree of components. Sharing data between top-level parent components to one of the children in the lowest ( deepest ) level of this component tree can be cumbersome. This situation is known as “prop drilling”. “Prop drilling” make your code not only verbose code but also can affect the performance of the application. In addition, fixing bugs can be more challenging.

What is React context?

React context is a storage to hold data that is common to child components. Imagine, you have a mid to large-size React application with nested child components. With React context, you do not need to pass data from a top-level parent component to a child component at the deep level of the component tree. Instead of passing data via props, you store the data in React context. Then, the child components can use the data in the Context.

How to make use of React context

There are three steps you need to do to utilize React Context in your application.

1. Create a Context

To create a context in React, you can use the createContext() function provided by React. Here’s how you can create a context:

//Import the necessary dependencies
import React, { createContext } from 'react';
//Create the context using createContext(). defaultValue is optional
const MyContext = createContext(defaultValue);
//Export the context object
export default MyContext;

2. Create a Context provider

A context provider is a component that supplies the context values to its descendant components. It is responsible for defining and sharing the data or state that can be accessed by components that use/consume the context.

context provider is created using the Context.Provider component provided by the context object. The provider component accepts a value prop, which represents the data or state to be shared with the consuming components.

export default function MyContextProvider({ children }) {  
const contextValue = { message:'Hello from the context!'};
return(
<MyContext.Provider value={contextValue}>
{children}
</MyContext.Provider>
);
}

Inside the provider component, the contextValue is the data or state that we want to share with the consuming components. In this case, our contextValue is an object with a message property.

MyContextProvider component expects a children prop. The children prop is then rendered inside the MyContext.Provider component, which makes the context values available to all the descendants of the provider component. value prop represents the context values that you want to provide.

When you want to use the provider, you need to wrap a portion of your component tree with the provider component (<MyContextProvider>), the context values defined in the provider will be accessible to the consuming components within that tree.

function App() {

const contextValue = 'Hello from context!';
return (
<MyContext.Provider value={contextValue}>
<Component1 />
<Component2 />
</MyContext.Provider> );
}

3. Consume the Context

There are two ways to use or consume the Context.

1. Using useContext hook

import React, { useContext } from 'react';
import { MyContext } from './MyContextProvider';export default function MyComponent() {
// Consume the context values using the useContext() hook
const contextValue = useContext(MyContext);
return (
<div>
<p>Context Value: {contextValue}</p>
</div>
);
}

The useContext() hook takes the context object ( MyContext ) as an argument and returns the current value of the context. In this case, contextValue will hold the context value provided by the nearest MyContext.Provider ancestor component.

2. Using MyContext.Consumer component

import React from 'react';
import { MyContext } from './MyContextProvider';

export default function MyComponent() {
return (
<div>
<MyContext.Consumer>
{(contextValue) => (
<p>Context Value: {contextValue}</p>
)}
</MyContext.Consumer>
</div>
);
};

The <MyContext.Consumer> component is used to consume the context values within your component. It follows the render prop pattern, which means it expects a function as its child. This function receives the current context value as an argument and returns the JSX that should be rendered.

What are the Use cases of React context?

Some of the use cases of React Context are:

  1. Theming: Allowing components to dynamically change their visual styles based on the selected theme.
  2. Localization: Providing translated strings or language settings to components for internationalization purposes.
  3. User Authentication: Sharing user authentication status or user information across multiple components.
  4. State Management: Replacing or supplementing state management libraries like Redux for smaller-scale applications.
  5. Dark Mode: Enabling components to switch between light and dark mode based on user preferences.
  6. Dynamic Configurations: Sharing configuration settings or variables across multiple components.
  7. Component Communication: Facilitating communication between unrelated components without passing props through intermediate components.
  8. App-wide Settings: Sharing app-wide settings or preferences across different parts of the application.
  9. Multi-step Wizards: Managing and sharing state between different steps of a multi-step form or wizard.
  10. Caching and Data Fetching: Caching fetched data and shared it among components to avoid redundant API requests.

Please note this is not an exclusive list. There can be many other cases you can use React Context.

What are the advantage and disadvantages of using React context?

While React Context offers many advantages, it can also introduce some disadvantages too. Some of them are:

When to use React Context

  1. You have data or state that needs to be shared across multiple components without passing props through intermediate components.
  2. You have a small to medium-sized application where a centralized state management solution like Redux might be overkill.
  3. You want to avoid prop drilling and make your component tree more maintainable and readable.
  4. You have a few critical pieces of global or app-wide state that need to be accessible by various components.
  5. You want to create reusable components that can adapt to different contexts and environments.

When not to use React Context

  1. You have a large-scale application with complex state management requirements that might be better suited for a dedicated state management library like Redux.
  2. Performance is a critical concern, as frequent context updates and unnecessary re-renders can impact performance.
  3. Overuse of context can lead to a tightly-coupled component tree and make code maintenance and refactoring challenging.
  4. The context value is constantly changing or requires frequent updates, as this can impact performance and complicate the codebase.

Conclusion

In summary, React Context provides a convenient way to share data and states across components in a React application. It offers advantages such as centralized data management, reduced prop drilling, improved code readability, and the ability to create reusable components. However, it’s important to be cautious of potential challenges like increased complexity, performance impacts, overuse of global state, context dependencies, and testing complexities. By carefully considering the specific requirements and trade-offs of your project, you can determine whether React Context is a suitable choice for your application.

Resources

React Context official documentation

--

--