React Basics - useContext Hook

 

React Basics: useContext Hook

Use case: You have pieces of data that need to be shared globally amongst components (or, not even quite globally, just shared in different places in your application). Props drilling, for what it is... nah. Redux? Well, maybe but what an expensive solution if your application just doesn't need that kind of horsepower....

The useContext hook lets you share data among components as needed, it's easy to set up and from what I hear, it's rather performant. Word on the street is that Redux actually uses useContext hooks internally, but that's just a vicious rumor....

The code below is courtesy of the Scrimba course React Bootcamp: Become a Pro React Developer (https://scrimba.com/p/pMvMEuD/caqbeZTw)

App.js

Simple, straightforward page layout that displays a header and a button. Nothing special, except they're different components.
import React from "react"

import Header from "./Header"
import Button from "./Button"

function App() {
    return (
        <div>
            <Header />
            <Button />
        </div>
    )
}

export default App


themeContext.js

While I won't yet refer to this file as "the store" this IS the file where the data lives that needs to be shared and/or displayed in multiple components.
NOTE: The typical convention for this file is to name it with your subject matter in mind; this file decorates our theme hence "themeContext". If you need a bunch of data about pizza then you might use "pizzaContext" for the name.
const ThemeContext = React.createContext()

class ThemeContextProvider extends Component {
    state = {
        theme: "dark"
    }
    
    toggleTheme = () => {
        this.setState(prevState => {
            return {
                theme: prevState.theme === "light" ? "dark" : "light"
            }
        })
    }
    
    render() {
        return (
		//add the data you need to make available for the other components here in the value attribute of this tag.
            <ThemeContext.Provider value={{theme: this.state.theme, toggleTheme: this.toggleTheme}}> 
                {this.props.children}
            </ThemeContext.Provider>
        )
    }
}

export {ThemeContextProvider, ThemeContext}


Button.js

Your standard, regulation button, but the onClick method and the class name are passed in via context
import React, {useContext} from "react"  //import useContext
import {ThemeContext} from "./themeContext" //import the file with the data you need for this component

function Button(props) {
    const context = useContext(ThemeContext) //declare the context from the imported file
    return (
        <button onClick={context.toggleTheme} className={`${context.theme}-theme`}>
            Switch Theme
        </button>
    )    
}

export default Button


Header.js

This is usually a UI feature displayed on a web page, maybe nav and other menus are inside....
import React, {useContext} from "react" //import useContext
import {ThemeContext} from "./themeContext" //import the file with the data you need for this component

function Header(props) {
    const context = useContext(ThemeContext) //declare the context from the imported file
    return (
        <header className={`${context.theme}-theme`}> /*here is where you directly reference the 
		values in the imported context */
            <h2>{context.theme === "light" ? "Light" : "Dark"} Theme</h2> //here too
        </header>
    )    
}

export default Header


Index.js

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

import App from "./App"
import {ThemeContextProvider} from "./themeContext" /*import the file with the data needed 
for the components*/

ReactDOM.render(
    <ThemeContextProvider> /*...because the ThemeContext file is configured with props children 
	any component that needs to use it must be wrapped in the tags */
        <App />
    </ThemeContextProvider>, 
    document.getElementById("root")
)



 
 
Link your website to this page! Copy and paste the URL below:
http://www.cfsnap.com/react/react-basics-usecontext-hook/