An Intro to useContext in React.js
Tags: react, html, javascript
Published: 2022-09-19 13:54:22

An aspect of React that I never like is the transfer of state values between components, and requiring props to be passed to both give values of state, as well as update them. The useContext hook can make this process a slight bit easier by allowing you to manage state globally, and for nested components especially, they have an easier time without the need to pass props.

## How to Begin

The most conventional approach to using this hook is to initialize the context (global state value), and give it the ability to pass a value down to components. This first step to initialize UserContext as a variable is all done within its own file, for me, named CreateContext.js:

```javascript
import { createContext } from "react";

export const UserContext = createContext();
```
This is all the required code in that file. Now we can go to our page, which in my case, my App.js is structured as so:

```javascript
function App() {
  return (
    <Router>
      <div className="page">
        <div>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/results/">Results</Link>
          </li>
        </div>
        <Routes>
            <Route exact path="/" element={
            <Home />
            }/>
            <Route path="/results" element={
            <Results />
            }/>
        </Routes>
      </div>
    </Router>
  );
}
```
Here is what we're looking at:

**Home**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2do6ug1r9s3z0ibtj95s.png)

**Results**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eor9cp2o6c9d1olv45e0.png)

For my simple example, the idea is to create an input from the input-box, set it to the global state value, then access it from our results page. Here is how to initialize that value, then wrap it around the components we want to access that information:

```javascript
import React, { useState } from 'react';
import Home from './Home';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Results from './Results';
import { UserContext } from './CreateContext';

function App() {
  const [value, setValue] = useState("default")

  return (
    <Router>
      <div className="page">
        <div>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/results/">Results</Link>
          </li>
        </div>
        <UserContext.Provider value={{ value, setValue }}>
          <Routes>
              <Route exact path="/" element={
                <Home />
              }/>
              <Route path="/results" element={
                <Results />
              }/>
          </Routes>
        </UserContext.Provider>
      </div>
    </Router>
  );
}
```
We are at the highest level of the application, and the highest place we want to access the information. We have passed along a value to the global state, which has been set to the variable "value", meaning it is initialized as "default".

Now, if we want to access that value, we can do it as such:

```javascript
import { useContext } from "react";
import { UserContext } from './CreateContext';

export default function Results(){
    const { value } = useContext(UserContext)

    return(
        <div>
            <p>Results: {value}</p>
        </div>
    )
}
```

This is the results page, and it is using the useContext function to grab a value out of "UserContext", which it is then displaying:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/crewsn12xzu8mowulfxu.png)

Now, to update this value, I can go to my Home page, and change the input field, which has been set to the same global state value, "default".

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rn94oi95snqx01vrkvrv.png)

Here is how I am grabbing that value:

```javascript
import { useContext } from "react";
import { UserContext } from './CreateContext';

export default function Home(){
    const { value, setValue } = useContext(UserContext);

    return(
        <div>
            <p>Enter a value: </p>
            <input
                type="text"
                placeholder="enter value..."
                value={value}
                onChange={(e) => setValue(e.target.value)}
            />
        </div>
    )
}
```

We are also able to update it with this function, with the onChange utilizing the setter function. As you can see, this step looks almost identical to useState. We are using the hook function to grab a value, and de-structure it to allow us to both use what's stored, and set it by passing the setter function a new value.