ReactJS

How to Use Context API in React

What is context ?In laymen term, Context means “the situation in which something happens or that caused something to happen”. Significance of...

Written by Luci · 3 min read >

What is context ?
In laymen term, Context means “the situation in which something happens or that caused something to happen”.

Significance of context in React
As per above definition, React Context will provide an encapsulation where in alteration of a variable happens and we access the same variable within the same context. Important thing to note here is that this encapsulation can contain multiple components and thus can help in variable sharing between components or variable propagation from top to bottom components or vice versa.

Let’s try to implement a basic scenario to understand this in better way.

Use Case

We are going to implement a basic counter application.

After user clicks on button — Increase Counter, Counter value increases by 1.

Important thing to note here is that the button and the header displaying the value are in different component and we are sharing the value in real time between components.

Let’s see how to implement the use case

  • First we will do the basic scaffolding of react application
npx create react-app counter template=typescript

Above command will create one basic React application.

Next we will create two basic components.

Header Component

// Header.tsx

const Header = () => {
    return(
        <h1>Counter value is </h1>
    )
}

export default Header;

Body Component

// Body.tsx

const Body = () => {
    const incCounter = () => {
        
    }
    return(
        <button onClick={incCounter}>
            Increase Counter
        </button>
    )
}

export default Body

Update App.tsx by removing all the code in return block with

// App.tsx
 
return (
    <>
      <Header/>
      <Body/>
    </>
  );

We have basic structure in place and now we will dive in implementing context.

  1. Create a file named as CounterContext.tsx and add below code
import { createContext, useState } from "react";

// Step 1
const CounterContext = createContext({
counter : 0,
handleCounter : () => {}
});

// Step 2
const CounterProvider = ({children}:{children:any}) => {
// Step 3
const [counter,setCounter] = useState(0);
//Step 4
const handleCounter = () => {
setCounter((prevValue:any) => prevValue + 1);
}
//Step 5
const counterObj = {counter,handleCounter}
// Step 6
return(
<CounterContext.Provider value={counterObj}>
{children}
</CounterContext.Provider>
)
}
// Step 7
export { CounterProvider , CounterContext}

Don’t get intimidated by so much lines of code as this is the basic crux of context and we will go through each and every line step by step.

  1. In Step 1 we have created the context using createContext named as counterContext. createContext is method which is provided by react which helps in creating a context within which all the components are encapsulated where in there is a need to access or share variables.
    Another thing to notice here is that createContext should expose the variables and methods which we need to access in encapsulated components, for e.g. in our example counter variable and handleCounter method are exposed.
  2. Context created in Step 1 has a Provider react component. Advantage of using this Provider is that it gives a wrapper around which we can wrap all the components where in we want to subscribe for context changes. Here in Step 2 we have created a function named as CounterProvider which returns a react Provider component.
  3. In Step 3, we have simply created a counter variable with useState hook and setter for the same using setCounter.
  4. In Step 4, we have create handleCounter method which will trigger the setter for counter variable.
  5. Step 5 is the real business where in we define the properties, methods which we need to expose to the components around which we have wrapped Provider. Do note here that the object structure defined in Step 1 should match with the object structure defined here, else you will get a Type mismatch error. You can think of the structure defined in Step 1 as an alias and the one defined in Step 5 as real implementation.
  6. Provider react component returned in Step 2 needs a value prop where in we pass the object defined in Step 5, so that the same can be available in enclosed components.
  7. Finally in Step 7 we export both the context and provider created so, the same can be accessed outside.

Through above mentioned step, we are done with the implementation of our CounterContext and in most of the cases these are the basic 7 steps which are needed, tough use case and complexity may vary.

Now, lets use this created context to implement our use case.

  • Once we have the CounterProvider component ready, we will use the same in App.tsx and wrap it around Header and Body component as shown below. We will wrap the Provider around the components where in we want to access the context.
return (
    <CounterProvider>
      <Header/>
      <Body/>
    </CounterProvider>
  );

Let’s make changes in Body component to trigger change of counter variable.

  • Body Component
import { useContext } from "react";
import { CounterContext} from './CounterContext';

const Body = () => {

const { handleCounter} = useContext(CounterContext); // Step 1
const incCounter = () => {       // Step 2
handleCounter();
}
return(
<button onClick={incCounter}>
Increase Counter
</button>
)
}

export default Body

In Step 1, we are using useContext api provided by React. It accepts an argument which is the name of the context. Once we pass in the context name, it will return the object or property passed in the value prop while returning Provider component. In our case, it will be like —

 <CounterContext.Provider value={counterObj}>
            {children}
        </CounterContext.Provider>

We get handleCounter property using destructuring .

2. In Step 2, we are calling the handleCounter on click of the button. If you recall the handleCounter method is the one where in we are setting the new counter value with setCounter. So, while clicking on Button the counter variable in the context is updated.

Now, let’s make changes in header component to subscribe the changes made to counter variable

  • Header Component

Once the value is updated by Producer we need to consume the same value in other component. Let’s make some changes in Header component for the same.

import { useContext } from "react";
import { CounterContext } from "./CounterContext";
const Header = () => {
const { counter } = useContext(CounterContext);   // Step 1 
return(
<h1>Counter value is - {counter}</h1>           // Step 2 
)
}
export default Header;
  1. In Step 1 we are again using useContext api and this time we are getting counter variable which is the updated value after click of button in Body component.
  2. In Step 2 we are displaying the counter variable.

This in nut shell is how we can use Context and useContext api to pass value from one component to other in React.

Do, let me know in response if you have any further queries.

Written by Luci
I am a multidisciplinary designer and developer with a main focus on Digital Design and Branding, located in Cluj Napoca, Romania. Profile
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x