When Should You Use useContext?

Context or useContext is primarily used when some data needs to be accessible by many components at different nesting levels. If you want, for example, to manage a state used across your hierarchy without having to explicitly pass the prop, useContext will be great.

Some examples could be a state manager for your online or offline status; many components will need to access this info to show a fallback UI or manage a centralized notifications or messages system.

How Do You Use useContext?

You have to use two different Hooks. The first one is createContext to build the context inside a variable, in our example, AppStateContext.

After that, you will be able to declare your AppStateProvider with functions and states related to its inner functionalities.

import React, { useEffect } from "react"

export const AppStateContext = React.createContext(null)

export default function AppStateProvider({ children }) {
const [message, SetMessage] = React.useState()
const [error, SetError] = React.useState()

const state = {
SetMessage: SetMessage,
SetError: SetError,
}

useEffect(() => {
if (message !== undefined) alert(message)
}, [message])

useEffect(() => {
if (error !== undefined) alert(error)
}, [error])

return (
<AppStateContext.Provider value={state}>
{children}
</AppStateContext.Provider>
)
}

In the render, you will wrap the AppStateContext.Provider, passing it the variables created inside the AppStateProvider.

How Do You Add the Context to the App?

You just need to wrap the components inside AppStateProvider to be able to use the Context on all children of the AppStateProvider.

It’s the same behavior as the Apollo client provider.

import React from "react"
import ReactDOM from "react-dom"

import "./styles.css"

import AppStateProvider from "./AppStateProvider"
import SendANotification from "./SendANotification"
import SendAnotherNotification from "./SendAnotherNotification"

function App() {
return (
<AppStateProvider>
<div className="App">
<h1>Hello Medium!</h1>
<h2>useContext is great for global components!</h2>
<SendANotification />
<SendAnotherNotification />
</div>
</AppStateProvider>
)
}

const rootElement = document.getElementById("root")
ReactDOM.render(<App />, rootElement)

How Do You Access the Context?

Inside all the components where you need to use the Context, you will have to use the other, most important Hook, useContext! Passing it the AppStateContext.

After that, you will be able to access the values passed to the context. In this case, we have the functions SetMessage and SetError to manage all the notifications of our app in a centralized way.

You can also import only the values you need from the Context.

import React from "react"
import { AppStateContext } from "./AppStateProvider"

export default function SendANotification() {
const { SetMessage, SetError } = React.useContext(AppStateContext)

function SendButtonMessage() {
SetMessage("You just clicked a normal button!")
}

function SendButtonErrorMessage() {
SetError("You just clicked an error button!")
}

return (
<div>
<h3>Send a notification</h3>
<button onClick={SendButtonMessage}>Send Message</button>
<button onClick={SendButtonErrorMessage}>Send Error Message</button>
</div>
)
}

Complete CodeSandbox of This Tutorial

https://codesandbox.io/s/react-simple-usecontext-s4mdf

References and Resources