Context vs Props in React
Tags: react, webdev, tutorial
Published: 2022-12-23 23:14:55

Hey! Thanks for dropping in. This article focuses on the difference between React props and React Context. I’ll walk you through a, hopefully, familiar concept to teach you how to use Context and when to use props.

Before we begin, go ahead and check out [the code here](https://github.com/ryanAllMad/persons-context). And see [the app in action here.](https://ryanallmad.github.io/persons-context/)

Estimated reading time: 8 minutes

## The Concept

If you’ve ever studied JavaScript and have touched on or dived into Objects, then you’re probably familiar with [the Person example.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects) To jog your memory, below is a Person object in Vanilla JS:

```javascript
function Person(age, favoriteColor, hobbies, gender) {
this.age = age;
this.favoriteColor = favoriteColor;
this.hobbies = hobbies;
this.gender = gender;
}
```

And if I wanted to create an object from this object (aka prototypal inheritance) then I’d do something like this:

```javascript
const Mykol = new Person("30", "blue", "kicking ass, taking names", "female")
```

Now that Mykol is a Person object, I can access information about her like this:

```javascript
console.log(Mykol.age)
```

Hopefully the above concept makes some sense to you. We’re going to use this same Person example to create a React app that uses both props and context to show the difference of these two concepts and when to use them.

For our project we’re going to use three friends and co-workers who all have individual qualities (as humans do) and one thing in common: they won’t go to the company retreat unless their friends are going.

Looking for more fun with Javascript concepts in React? [Check out this Array Methods in React post here.](https://allmaddesigns.com/array-methods-in-react/)

## Getting Started

As always, we’re going to navigate to a project folder in our VS Code and open a terminal. Here we’ll use the Create React App command to spin up a React App:
```javascript
npx create-react-app persons-context
```

After that’s done:

- remove all of the code inside the App.css file and save.
- inside the App.js file, remove everything except the div with the className="App"
- create a folder in the /src directory titled ‘components’
- create a folder in the /src directory and title it ‘context’

Your App is now scaffolded and ready for us to begin working. If you want to add some text inside the App.js file inside the div with the className=”App” and run npm start in your terminal, you should. That can give you a good idea if you’ve scaffolded your project correctly or not.

## Context

We’re going to start with our Context component. In this component we want to share the value that our Person’s components will share: Whether they are going to go to the company retreat or not.

- Inside the /context folder create a file called PersonContext.js.
- at the top of the file add: import { createContext, useState } from 'react'
- on a new line add const PersonContext = createContext()
- on a new line create the following function:

```javascript
export const Provider = ({children}) => {
const [retreatStatus, setRetreatStatus] = useState('not going')

const data = {
        retreatStatus,
        changeRetreatStatus: () => {
            setRetreatStatus('going')
        }
    }

    return <PersonContext.Provider value={data}>{children}</PersonContext.Provider>
}
```

Finally, at the bottom of the file, add your default export:

```javascript
export default PersonContext
```

> Note that now you have a named export “Provider” and a default export “PersonContext”. Pay attention to the way we import these two exports to understand the difference between named exports and default exports.

## How to Utilize Context

So that our app can utilize the Context we’ve just created, we need to navigate to our index.js file. At the top of this file, under your other import statements, import the named Provider export like so:

```javascript
import { Provider } from './context/PersonContext'
```
Inside the root.render function, we’re going to wrap our App component with the Provider component we’ve just imported.

```javascript
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider>
      <App />
    </Provider>
  </React.StrictMode>
);
```
That’s all we have to do to ensure that our components have access to the Context we’ve just created. But we still haven’t started using the context system yet. We’re going to move on to using props now and come back to how to access this Context in our components when it makes more sense to do so.

## The Components

Inside of our /components folder, we’re going to create a Person component, an AriaLive component and three “People” components. Feel free to name these people whatever you want, I’m going to use my friends in this example.

### Person Component

Starting with the Person component, in the /components folder create a file called Person.js

At the top of the file add your import statement like so:

```javascript
import React, { useState, useEffect  } from "react"
```

> Note: notice that we are not using Context in this component, this is very important because this is a ‘parent’ component to our other components, yet there is no need to use Context here.

Next lets create our person. This component is going to use a lot of props, props that our child components are going to need. Under the import statements on a new line add the Person functional component:

```javascript
const Person = ({ name, children, age, favoriteColor, hobbies, gender }) => {
    const [pronouns, setPronouns] = useState({subject: 'they', object: 'them'})
    const changePronouns = () => {
    if( gender === 'male') {
        setPronouns ({
            subject: 'he',
            object: 'him'
        })
    }
    if(gender ==='female') {
        setPronouns({
            subject: 'she',
            object: 'her'
        })
    }
   } 
   useEffect(() => changePronouns(), [])
    return (
    <div className={name}>
        <h3>{`${name.toUpperCase()}`}</h3>
        <h4>{age}</h4>
        <p>Gender: {`${gender}`}</p>
        <p>{`${name.toUpperCase()}`}'S favorite color is {`${favoriteColor}`}. {`${pronouns.subject.toUpperCase()}`} enjoys {`${hobbies}`}. 
        Today {`${pronouns.subject}`} is {children}
            to the company retreat. 
        </p>
    </div>
    )
}
```

This component probably looks very complicated and it does have some complexity. Let’s break it down. The component makes use of the following props:

- name
- children (not actual children, but React children)
- age
- favoriteColor
- hobbies
- gender

We are creating a piece of state for the pronouns. These pronouns are an object with 2 properties, the subject pronouns (such as he, she, they) and the object pronouns such as (him, her, them).

After that we are calling a function within the useEffect hook that will render the correct pronouns depending on the person’s gender.

Not too difficult when you break it down.

## Context vs Props

### Jason – A Person component

We’ll use Jason as our main example because he’s a great guy and we stan. Inside our components folder we’ll create a file called Jason.js

At the top of our file we’re going to import something new here, the useContext hook. And this will allow us to finally use the Context component we’ve created.

```javascript
import React, { useContext } from "react"
import PersonContext from "../context/PersonContext"
import Person from "./Person"
```

### The Person Props

We’ll create our Jason functional component and assign the Person props some values. Notice how these values are individual values? I’ve left a comment where the children prop is being called. We’ll set that up next.

```javascript
const Jason = () => {
    return  (
    <Person age="36" name="jason" favoriteColor="black" hobbies="writing, making stacks" gender="male">
        {/*something will go here*/}
    </Person>
    )

}

export default Jason
```

Next its time to use the Context system finally. Below I’ve updated the Jason component. We are destructuring out the retreatStatus and changeRetreatStatus context from the PersonContext Provider. We are then creating a button component that will use these pieces of Context.

```javascript
const Jason = () => {
    const { retreatStatus, changeRetreatStatus } = useContext(PersonContext)
    return  (
    <Person age="36" name="jason" favoriteColor="black" hobbies="writing, making stacks" gender="male">
        <button onClick={changeRetreatStatus}>{retreatStatus}</button>
    </Person>
    )

}

export default Jason
```

Now in my App.js file I am going to import Jason into this file and return the Jason component within my App.

```javascript
import React from "react"
import './App.css';
import Jason from './components/Jason';


function App() {
  return (
    <div className="App" role="main">
      <h1>Person Context App</h1>
      <h2>These are people. They all are individuals, but they have one thing in common, 
        they won't go to a retreat unless their friends are going too.</h2>
      <Jason />
    </div>
  );
}

export default App;

```
I’ll repeat this process to make 2 more people. My App now looks like this below:

```javascript
import React from "react"
import './App.css';
import Jason from './components/Jason';
import Mykol from './components/Mykol';
import Ryan from './components/Ryan';

function App() {
  return (
    <div className="App" role="main">
      <h1>Person Context App</h1>
      <h2>These are people. They all are individuals, but they have one thing in common, 
        they won't go to a retreat unless their friends are going too.</h2>
      <Jason />
      <Mykol />
      <Ryan />
    </div>
  );
}

export default App;
```

### AriaLive – An accessibility feature

I like accessibility and aim to make everything I build be as accessible as possible. Therefore, so that this project would alert a non-visual user to changes in the document, I have created an AriaLive component within my /components folder. Below is the simple code for this component:
```javascript
import React from "react"

const AriaLive = () => {

    return <span className="screen-reader-text" aria-live="polite">All of the friends are now going to the retreat</span>
}

export default AriaLive
```

Here’s where it gets cool. Back in my App component I’m going to import this component and I want to conditionally render this aria-live region to my non-visual users when the retreatStatus changes to ‘going’. How I do this is by using Context once again.

I’ll first import useContext again and PersonContext. Then I’ll import the AriaLive component so that my import statements in my App.js file look like this once complete:

```javascript
import React, { useContext } from "react"
import PersonContext from "./context/PersonContext"
import './App.css';
import Jason from './components/Jason'
import Mykol from './components/Mykol'
import Ryan from './components/Ryan'
import AriaLive from './components/AriaLive'
```

Before my return statement I want to destructure the retreatStatus value from the PersonContext component. This is the only value I really need in my App component.

```javascript
  const { retreatStatus } = useContext(PersonContext)
```

Finally, within my App components return statement, I’m going to conditionally render this aria-live region like so:

```javascript
  return (
    <div className="App" role="main">
      <h1>Person Context App</h1>
      <h2>These are people. They all are individuals, but they have one thing in common, 
        they won't go to a retreat unless their friends are going too.</h2>
      <Jason />
      <Mykol />
      <Ryan />
      {retreatStatus === 'going' && <AriaLive />}
    </div>
  );
```
Want to learn more about what Aria actually is? [Check out this WTH is WAI-ARIA post here.](https://allmaddesigns.com/wth-is-wai-aria/)

## Conclusion

This article focused on the difference between React props and React Context. Hopefully this project helped you to get familiar with these concepts and when to use each and why. Context is best to use when you want to pass values throughout your components but not necessarily from parent to child. Context is used well when the value is something your components share. Props are like individual traits, props get passed down from parent to child and are best used for defining individual properties. Hopefully the difference between Context and Props is a lot more clear to you. Thanks again for stopping by and for reading all the way to this part (impressive!).