×
☰ See All Chapters

React Context API

The Context API is a neat way to pass state across the app without having to use props. The Context API was introduced to allow you to pass state (and enable the state to update) across the app, without having to use props for it. The React team suggests to stick to props if you have just a few levels of children to pass, because it's still a much less complicated API than the Context API. In many cases, it enables us to avoid using Redux, simplifying our apps a lot, and also learning how to use React.

React Context is a way to manage state globally. It can be used together with the useState Hook to share state between deeply nested components more easily than with useState alone.

Context API in function components

Create a context using React.createContext(), which returns a Context object:

const UserContext = createContext();

 

Create a wrapper component that returns a Provider component, and you add as children all the components from which you want to access the context:

function DemoComponent() {

  const [message, setMessage] = useState("Hello World!");

 

  return (

    <MessageContext.Provider value={message}>

      <h1>Message printed in component 1 is {message}</h1>

      <Component2 />

    </MessageContext.Provider>

  );

}

Note <Component2 /> is kept inside provider. If <Component2 /> is kept outside provider as below you cannot consume the context from inside component2 or component3.

function DemoComponent() {

  const [message, setMessage] = useState("Hello World!");

 

  return (

    <MessageContext.Provider value={message}>

      <h1>Message printed in component 1 is {message}</h1>

    </MessageContext.Provider>

    <Component2 />

  );

}

 

In order to use the Context in a child component, we need to access it using the useContext Hook.

function Component3() {

  const message = useContext(MessageContext);

 

  return (

    <>

      <h2>Component 3</h2>

      <h1>{`Message printed in component 3 is ${message}`}</h1>

    </>

  );

}

Note You should include the useState, createContext and useContext in the import statement to while using context API as shown in the full example below:

Full Example

demo.component.js

import { useState, createContext, useContext } from "react";

 

const MessageContext = createContext();

 

function DemoComponent() {

  const [message, setMessage] = useState("Hello World!");

 

  return (

    <MessageContext.Provider value={message}>

      <h1>Message printed in component 1 is {message}</h1>

      <Component2 />

    </MessageContext.Provider>

  );

}

 

function Component2() {

  return (

    <>

      <h2>Component 2</h2>

      <Component3 />

    </>

  );

}

 

function Component3() {

  const message = useContext(MessageContext);

 

  return (

    <>

      <h2>Component 3</h2>

      <h1>{`Message printed in component 3 is ${message}`}</h1>

    </>

  );

}

 

export default DemoComponent;

index.js

import React from 'react';

import ReactDOM from 'react-dom';

import './index.css';

import DemoComponent from './components/demo.component';

import reportWebVitals from './reportWebVitals';

 

ReactDOM.render(

  <React.StrictMode>

    <DemoComponent></DemoComponent>

  </React.StrictMode>,

  document.getElementById('root')

);

 

reportWebVitals();

Output:

react-context-api-0
 

Context API in class components

Create a context using React.createContext(), which returns a Context object:

const { Provider, Consumer } = React.createContext();

 

Create a wrapper component that returns a Provider component, and you add as children all the components from which you want to access the context:

class DemoComponent extends React.Component {

        constructor(props) {

                super(props)

                this.state = {

                        message: 'Hello World'

                }

        }

        render() {

                return (

                        <>

                                <h1>Message printed in component 1 is {this.state.message}</h1>

                                <Provider value={{ state: this.state }}><Component2 /></Provider>

                        </>

                )

        }

}

Note <Component2 /> is kept inside Provider. If <Component2 /> is kept outside Provider as below you cannot consume the context from inside component2 or component3.

class DemoComponent extends React.Component {

        constructor(props) {

                super(props)

                this.state = {

                        message: 'Hello World'

                }

        }

        render() {

                return (

                        <>

                                <h1>Message printed in component 1 is {this.state.message}</h1>

                                <Provider value={{ state: this.state }}></Provider>

                                <Component2 />

                        </>

                )

        }

}

 

In order to use the Context in a child component, we need to access it using the Consumer component.

class Component3 extends React.Component {

        render() {

                return (

                        <>

                                <h2>Component 3</h2>

                                <Consumer>

                                        {context => <h1>Message printed in component 3 is {context.state.message}</h1>}

                                </Consumer>

 

                        </>

                )

        }

}

Full Example

demo.component.js

import React from 'react';

 

const { Provider, Consumer } = React.createContext();

 

class DemoComponent extends React.Component {

        constructor(props) {

                super(props)

                this.state = {

                        message: 'Hello World'

                }

        }

        render() {

                return (

                        <>

                                <h1>Message printed in component 1 is {this.state.message}</h1>

                                <Provider value={{ state: this.state }}><Component2 /></Provider>

                        </>

                )

        }

}

 

class Component2 extends React.Component {

        render() {

                return (

                        <>

                                <h2>Component 2</h2>

                                <Component3 />

                        </>

                )

        }

}

 

class Component3 extends React.Component {

        render() {

                return (

                        <>

                                <h2>Component 3</h2>

                                <Consumer>

                                        {context => <h1>Message printed in component 3 is {context.state.message}</h1>}

                                </Consumer>

 

                        </>

                )

        }

}

export default DemoComponent;

index.js

import React from 'react';

import ReactDOM from 'react-dom';

import './index.css';

import DemoComponent from './components/demo.component';

import reportWebVitals from './reportWebVitals';

 

ReactDOM.render(

  <React.StrictMode>

    <DemoComponent></DemoComponent>

  </React.StrictMode>,

  document.getElementById('root')

);

 

reportWebVitals();

Output:

 

All Chapters
Author