Open In App

How to share state across React Components with context ?

Last Updated : 29 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In a small app, React Context along with useState is the best way to share state or simply pass data around components without mutating it.

Context: It provides a way to share values between components without having to explicitly pass a prop through every level of the tree.

React useState Hook: It is a Hook that allows you to have state variables in functional components. You pass the initial state to this function and it returns a variable with the current state value (not necessarily the initial state) and another function to update this value.

Example: Program to demonstrate the React context with the useState hook. In this example we have two buttons increase and decrease to change the count variable and a button to move to another page and see the updated count value.

Creating React Application:

Step 1: Create a React application using the following command:

npx create-react-app example

Step 2: After creating your project folder i.e. example, move to it using the following command:

cd example

Project Structure: It will look like this:

Here ComponentTwo is nested inside ComponentOne and ComponentOne is nested inside PageOne. We want to change the count variable in ComponentTwo.js and pass the data to see the updated value in PageTwo.js file. So without passing down the data through prop manually we are going to create the variable globally with the help of useContext and useState.

Steps to demonstrate the above example:

Step1: Creating Context: Create the context using createContext() method.

Syntax:

const Context = React.createContext();

Step 2: Creating set of data

Now we have a set of data that we need to store globally so that it can be accessed through any component. So in the Context.js file write the following code:

Javascript




// Context.js
import React, { useState } from "react";
 
export const Context = React.createContext();
export const ContextProvider = ({ children }) => {
    const [items, setItems] = useState(0);
 
    return (
        <Context.Provider value={{ items, setItems }}>
            {children}
        </Context.Provider>
    );
};


In this code, data is created using the useState hook and On Context. Provider, we put the value that we want to pass down our entire component tree. We set that equal to the value prop to do so. In this case value={{items,setItems}}.

Step3: Wrapping the app component.

Before trying to access the context value in our project wrap the app.js file with Context.Provider file. Go to the index.js file in your project and write the following code:

Javascript




// index.js
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { ContextProvider } from './Context';
 
ReactDOM.render(<ContextProvider><App /></ContextProvider>,
document.getElementById('root'));


Step 4: Accessing and updating the context

Now any component of the project has access to update and use a global variable. In order to use the Context in a child component, we need to access it using the useContext Hooks.

Javascript




// ComponentTwo.js
import React, { useContext } from "react";
import { useNavigate } from "react-router-dom";
import { Context } from "../Context";
 
function ComponentTwo() {
    const navigate = useNavigate();
    const { items, setItems } = useContext(Context);
     
    const clickHandler = () => {
        setItems((prevcount) => prevcount + 1);
    };
     
    const clickHandlerOne = () => {
        setItems((prevcount) => prevcount - 1);
    };
     
    const HandlerOne = () => {
        navigate("/pagetwo");
    };
     
    return (
        <div>
            <button onClick={clickHandler}>Increase</button>
            Count:{items}
            <button onClick={clickHandlerOne}>Decrease</button>
            <div>
                <button onClick={HandlerOne}>Move to Page Two</button>
            </div>
        </div>
    );
}
 
export default ComponentTwo;


Step 6: Access the variable from the other component.

Javascript




// PageTwo.js
import React, { useContext } from "react";
import { useNavigate } from "react-router-dom";
import { Context } from "../Context";
 
function PageTwo() {
    const navigate = useNavigate();
    const { items, setItems } = useContext(Context);
    const handlertwo = () => {
        navigate("/");
    };
     
    return (
        <div>
            <h2>Welcome to Page Two</h2>
            Updated new value Count:<b>{items}</b>
            <div>
                <button onClick={handlertwo}>Move to Page One</button>
            </div>
        </div>
    );
}
 
export default PageTwo;


Javascript




// App.js
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import PageTwo from "./pages/PageTwo";
import PageOne from "./pages/PageOne";
 
function App() {
    return (
        <div>
            <Router>
                <Routes>
                    <Route exact path="/" element={<PageOne />} />
                    <Route exact path="/pagetwo" element={<PageTwo />} />
                </Routes>
            </Router>
        </div>
    );
}
 
export default App;


Step to run the application: Run the application using the following command:

npm start

Output: Now, open the URL http://localhost:3000/, you will see the following output.

Conclusion: A simple and extensible way to share data through nested child components without passing any states or data props to the child component, using React Context and Hooks.  



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads