State or Context? The answer will shock you...
Tags: react, javascript, beginners
Published: 2021-11-19 14:09:21

As always, this is a post I'm using to help teach myself something! Hopefully this helps you too.

*This post does assume a basic knowledge of React, with a degree of familiarity with the concept of state.*

#### State -- A Reintroduction

I would not be surprised if you've heard of `useState`, which is a hook provided by React that allows us to set information dynamically, and monitor it in a manner that will allow our components to change along with updates to that information.

``` jsx
import React, { useState } from 'react';

function App () {
    const [ playList, setPlayList ] = useState ([
        { 
          id:1,
          genre:"Alternative",
          title:"You and I",
          artist:"Toro y Moi",
          track: "/tracks/you_and_i.mp3"
        }, { 
          id:2,
          genre:"Rock",
          title:"Khuda Bhi Aasman",
          artist:"Khruangbin",
          track: "/tracks/khuda_bhi_aasman.mp3" 
        }, { 
          id:3,
          genre:"Rock",
          title:"Goodie Bag",
          artist:"Still Woozy",
          track: "/tracks/goodie_bag.mp3"
        }  
    ])

return(
    <div className=music-box>
        <MusicBox playlist={playlist} setPlaylist={setPlaylist} />
    </div>
)}
export default App
```
Take this application above... Well let's just say this one piece, of this one, small application...

The information that we are putting into state is our playlist, and we're passing that down via props. Cool. We can imagine that `MusicBox` will probably use the information to populate some interface.

*But what if our application isn't so small?*

What if nested inside of Music box are tens of elements, in charge of various functionalities ranging that could include:
- A playlist interface that can be re-ordered, added to, deleted from, etc.
- An album image component that uses a pre-associated relationship to the track playing.
- A audio visualization component that displays an equalizer that responds to currently playing music.
- A suggested tracks component that takes the genre and returns tracks of the same kind.

*Maybe all of the above???*

If we wanted to bake all of that functionality into our app, chances are we're going to have a ton of components, in various branches of the application, that would all need access to the current `playlist` value. Also, it would be a safe bet that not every component would need every value *inside* of `playlist`. We could still pass everything down manually via `prop drilling` but that could get cumbersome if we are also passing other prop values declared within smaller subsections of the application.

![Why?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4g2kwgu9lc4bez936f3.gif)

#### Enter Context
This precise kind of dilemma is the exact reason `context` exists. Imagine if you only had to declare your state that a whole application might need pieces of in a single spot, and only call those values when and where you needed them, no need for prop drilling!

**So now we need to do that instead for our application.**
____
#### Step 1: Create Context and the Provider
Think of it like this, `Context` is the container, `Provider` is what lets your application components reach into the container.

Let's set this context up for our music application and get our remarkably small playlist stored in there instead!
``` jsx
import React,{ useState } from "react";

//Container
const PlaylistContext = React.createContext();

//Allows access to the container
function PlaylistProvider({ children }) {
    const [ playList, setPlayList ] = useState ([
        { 
          id:1,
          genre:"Alternative",
          title:"You and I",
          artist:"Toro y Moi",
          track: "/tracks/you_and_i.mp3"
        }, { 
          id:2,
          genre:"Rock",
          title:"Khuda Bhi Aasman",
          artist:"Khruangbin",
          track: "/tracks/khuda_bhi_aasman.mp3"
        }, { 
          id:3,
          genre:"Rock",
          title:"Goodie Bag",
          artist:"Still Woozy",
          track: "/tracks/goodie_bag.mp3"
        }  
    ])

    return(
        <PlaylistContext.Provider value={{ playList, setPlayList }}>
          {children}
        </PlaylistContext.Provider>;
    ) 
}

export { PlaylistContext, PlaylistProvider };
```
Boom. 
____
#### Step 2: Building the bridge
So far we have only built the storage container and the means to **_provide_** access to it. Now we have to connect that means of access into our application.

To do this we simply wrap the parent most component that will house all components that could need access to the context information with our `Provider`.

Let's revisit our earlier `App` component and see what it looks like now.
``` jsx
import React from 'react';

//This is our means of access
import { PlaylistProvider } from "./user";

function App () {
    return(
        <PlaylistProvider>
            <div className=music-box>
                <MusicBox />
            </div>
        </PlaylistProvider>
)}
export default App
```
Just like that, any component rendered within `MusicBox` or lower can now gain access to our playlist state. Up until now however, we have merely built the bridge from our context to the components that need to access them. We still need to cross the bridge and bring back the information.
____
#### Step 3: Crossing the bridge

Okay, so, you find yourself in a component for your music app that is 10 layers deep and now you need a new portion of the playlist info. Let's see how to access that information.

``` jsx
import { useContext } from 'react';

//Bridge crossed
import { UserContext } from "./user";

function Artists () {

    //Back across the bridge now with data
    const playlist = useContext(PlaylistContext);

    const playlistArtists = playlist.map(song => {
        return <ArtistTile key={song.id} artist={song.artist} />
    }
 
    return(
        <div className=playlist-artists>
            {playlistArtists}
        </div>

)}
export default App
```

There you have it! Context in use. What a great way to clean up our code base and help to isolate our information down into as few locations as possible! Now, you may be tempted to just use `Context` whenever you want to monitor state in your app. Let's explore why this is not such a great choice.

____
>**_"No need to worry about having to pass props!"_**
>--You, probably, the first time you heard about context
____

####Context Vs. State
Context provides us with abilities very similar to state. Both have the ability to monitor data, and control component re-renders as that data is updated. However, context is something that should, according to the people who wrote it, be used *sparingly*. This is because while component re-rendering is still possible with context, it is much more intensive on our applications to accomplish.