For enquiries call:

Phone

+1-469-442-0620

April flash sale-mobile

HomeBlogProgrammingWhat is Context in React and How to Use it?

What is Context in React and How to Use it?

Published
30th Jan, 2024
Views
view count loader
Read it in
9 Mins
In this article
    What is Context in React and How to Use it?

    Consider yourself as an architect who is tasked with creating a futuristic town. Each structure reflects a piece of your larger plan, closely interrelated but different. As you develop, you must ensure that every structure you build has access to important supplies without having to navigate a maze of tunnels. Just like this architect, many React developers frequently struggle with managing state across their components. Context in React is a powerful feature similar to a futuristic town's central distribution system, redefining how data flows effortlessly between React components. The Context API or context in react provides a solution by allowing components to easily share state data without having to pass props through each level of the component tree. In this article, we'll dive deep into context in React from start to end, learning about its unique features and how it simplifies state management in React applications. Whether you're new to React or a professional developer looking to improve your knowledge of state management techniques, this guide will help you make the best possible use of the Context in React.

    What is Context in React?

    Have you ever wondered about passing data or using states between different components without Props? Or passing a state from the Parent to Child component without manually passing a prop at every level? To master usereducer hook in React concepts, click here. 

    Let’s understand with an example below:

    Here we have a parent component, app.js, where we have defined our states. We want to access the data on the last child's state, “Child 1.2,” in the chart below.

    app.js Parent Component
    app.js Parent ComponentThe ideal or older approach in React is to pass the data from the root component to the last component via Props. We have to pass props in each intermediary level so as to send in the last level. While this approach also works, the real problems begin if data is needed on a different branch i.e, Child 2.1 or Child 2.2 in the above chart…

    In order to solve this problem, we need to pass data from the root/top level of the application through all the intermediate components to the one where we want to pass the data, even though some intermediate components don't even need it.  

    This mind-numbing process is known as prop drilling,  

    Prop Drilling
    Prop Drillingwhere you’re passing the state from your root component to the bottom, and you end up passing the data via props through components that do not even necessarily need them

    One really good solution to solve the above problem is to use Context. 

    According to the React documentation: 

     “Context provides a way to pass data through the component tree without having to pass props down manually at every level”

    Ordinarily, we’d have used any state management library like Redux or used HOCs to pass the data in a tedious manner. But what if we don’t want to use it all? Here comes the role of the new Context API!

    In layman's words, it gives an approach to make specific data available to all components throughout the React component tree regardless of how deeply nested those components are.

    Context is just like a global object to the subtree of the React component.

    When to use the Context API

    The Context API is convenient for sharing data that is either global, such as setting the header and footer theme of a website or logic of user authentication, and many more. In cases like these, we can use the Context API without using any extra library or external modules.

    It can also be used in a multilingual application where we want to implement multiple languages that can be translated into the required text with the help of ContextAPI. It will save prop-drilling   

    In fact, in any situation where we have to pass a prop through a component, so it reaches another component, inside the tree is where we can use the Context API.

    Introducing The Context API

    The context API is a way to pass data from top components to bottom ones without manually passing it via props. Context is fundamentally utilized when some data needs to be accessible by numerous components at different nesting levels. 

    To create a new Context, we can use the React createContext function like the below:

    const MyContext = React.createContext(defaultValue);

    In React, data is often passed from a parent to its child component as a property. Here, we can also omit the default value which we have passed to the context if needed.

    React data passing from parent to its child
     React data passing from parent to its child 

    Let’s Get Started With Context

    Three things are needed to tap into the power of context:

    1. The context itself

    To create a context, we can use React.createContext method, which creates a context object. This is used to ensure that the components at different levels can use the same context to fetch the data.  

    In React.createContext, we can pass an input parameter as an argument which could be anything, or it can be null as well.

    import React from `react'; 
    const ThemeContext = React.createContext('dark');  // Create our context       
    export default ThemeContext;

    In this example, a string is passed for the current Context, which is “dark”. So we can say the current theme required for a specific component is Dark.  

    Also, we have exported the object so that we can use it in other places.

    In one app, React also allows you to create multiple contexts. We should always try to separate context for different purposes so as to maintain the code structure and better readability.

    We will see that later in our reading.  

    What next??

    Now, to utilize the power of Context in our example, we want to provide this type of theme to all the components.  Context exposes a pair of elements which is a Provider Component and a Consumer Component.

    2. A context provider

    Okay, so now we have our Context object. And to make the context available to all our components, we have to use a Provider.  

    But, what is Provider?

    According to the React documentation:

    "every context object comes with a Provider React component that allows consuming components to subscribe to context changes"

    In other words, the Provider accepts a prop (value), and the data in this prop can be used in all the other child components. This value could be anything from the component state.

    // myProvider.js
    import React from 'react';
    import Theme from './theme';
    const myProvider = () => (
    <Theme.Provider value='dark'>
    ...
    </Theme.Provider> 
    );
    export default myProvider;

    We can say that a provider acts just like a delivery service.

    prop finding context and deliverling it to consumer
    prop finding context and deliverling it to consumerWhen a consumer asks for something, it finds it in the context and delivers it to where it's needed.

    But wait, who or what is the consumer???

    3.  A context consumer 

    What is Consumer? 

    A consumer is a place to keep stored information. It can request the data using the provider and can even manipulate the global store if the provider allows it. 

    In our previous example, let’s grab the theme value and use it in our Header component. 

    // Header.js 
      
    import React from 'react'; 
    import Theme from './theme'; 
      
    const Header = () => ( 
       <Theme.Provider value='dark'> 
           <Theme.Consumer> 
               {theme => <div>Selected theme is {theme}</div>} 
           </Theme.Consumer> 
       </Theme.Provider> 
    ); 
      
    export default Header;

    Dynamic Context:  

    We can also change the value of the provider by simply providing a dynamic context. One way of achieving it is by placing the Provider inside the component itself and grabbing the value from the component state as below:

    // Footer.js 
    
      
    import React from 'react'; 
      
    class Footer extends React.Component { 
       state = { 
           theme: 'dark' 
       }; 
      
       render() { 
           return ( 
               <MyThemeContext.Provider value={this.state.theme}> 
                   <ThemedButtonHolder /> 
               </MyThemeContext.Provider> 
           ); 
       } 
    }

    Simple, no? We can easily change the value of the Provider to any Consumer.

    Consuming Context With Class-based Components

    We all pretty know that there are two methods to write components in React, which are Class-based components and Function based components. We have already seen a demo of how we can use the power of Context in class-based components.  

    One is to use the context from Consumer like “ThemeContext.Consumer,” and the other method is by assigning a context object from the current Context to the contextType property of our class.

    import React, { Component } from "react";
    import MyThemeContext from "../Context/MyThemeContext";
    import GlobalTheme from "../theme";
     
    class Main extends Component {
       constructor() {
           super();
       }
       static contextType = MyThemeContext;  //assign context to component
       render() {
           const currentTheme = GlobalTheme[this.context];
           return (
               ...
           );
       }
     
    }

    There is always a difference in how we want to use the Context. We can provide it outside the render() method or use the Context Consumer as a component.  

    Here in the above example, we have used a static property named as contextType which is used to access the context data. It can be utilized by using this.context. This method, however, limits your consumption, only one context at a time.

    Consuming Context With Functional Components

    Context with Functional based components is quite easy and less tedious. In this, we can access the context value through props with the help of useContext method in React.

    This hook (useContext) can be passed in as the argument along with our Context to consume the data in the functional component.

    const value = useContext(MyContext);

    It accepts a context object and returns the current context value.

    Our previous example looks like this:

    import React, { useContext } from 'react'
    import MyThemeContext from './theme-context'
     
    const User = props => {
       const context = useContext(MyThemeContext)
       return <p className={context.isLight ? 'light' : 'dark'}>...</p>

    Now, instead of wrapping our content in a Consumer component, we have access to the theme context state through the ‘context’ variable.

    But we should avoid using context for keeping the states locally. Instead of context, we can use the local state there.

    Use of Multiple Contexts

    It may be possible that we want to add multiple contexts in our application. Like holding a theme for the entire app, changing the language based on the location, performing some A/B testing, using global parameters for login or user Profile…

    For instance, let’s say there is a requirement to keep both Theme context and userInfo Context. The code will look like as:

    <ThemeProvider> 
      <UserInfoProvider> 
        ... 
      </UserInfoProvider> 
    </ThemeProvider>

    It’s quite possible in React to hold multiple Contexts, but this definitely hampers rendering, serving the ‘n’ number of contexts in the ‘m’ component and holding the updated value in each rendered component.

    To avoid this and to make re-rendering faster, it is suggested to make each context consumer in the tree a separate node or into different contexts.

    <ThemeContext.Provider value={theme}>
       <ColourContext.Provider value={colour}>
           <NavItem />
       </ColourContext.Provider>
    </ThemeContext.Provider>

    And we can perform the nesting in context as:

    <ThemeContext.Consumer>
       {theme => (
           <ColourContext.Consumer>
               {colour => (
                   <p>Theme: {theme} and colour: {colour}</p>
               )}
           </ColourContext.Consumer>
       )}
    </ThemeContext.Consumer>

    It’s worth noting that when a value of a context changes in the parent component, the child components or the components holding that value should be rerendered or changed. Hence, whenever there is a change in the value of the provider, it will cause its consumers to re-render.

    Conclusion

    In conclusion, context in React is especially useful when multiple components spread throughout the application require access to the same data or state. By decoupling components from their direct dependency on props, it improves code readability, simplifies component structures, and promotes reusability. However, while Context in React offers a convenient way to manage global state and data sharing, its use must be carefully considered. Excessive reliance on context in React for all state management may result in increased coupling between components, potentially compromising the application's maintainability and readability.

    Furthermore, for certain complex state management requirements, dedicated state management libraries such as Redux may  still be a better fit.!

    Having challenge learning to code? Let our experts help you with customized React courses!

    Profile

    KnowledgeHut .

    Author

    KnowledgeHut is an outcome-focused global ed-tech company. We help organizations and professionals unlock excellence through skills development. We offer training solutions under the people and process, data science, full-stack development, cybersecurity, future technologies and digital transformation verticals.

    Share This Article
    Ready to Master the Skills that Drive Your Career?

    Avail your free 1:1 mentorship session.

    Select
    Your Message (Optional)

    Upcoming Programming Batches & Dates

    NameDateFeeKnow more
    Course advisor icon
    Course Advisor
    Whatsapp/Chat icon