DEV Community

Nathanaël CHERRIER
Nathanaël CHERRIER

Posted on • Originally published at mindsers.blog on

Updating a React context from its consumer

Updating a React context from its consumer

Among the last novelties of ReactJS that have greatly bettered the DX (Developer eXperience) of the framework, there is the Context API and hooks. In this post, we'll talk about Context API.

⚠️ Read more of my blog posts about tech and business on my personal blog! ⚠️

I am not going to detail how the Context API works in this post. If you don't know what that is, I encourage you to go read the very good React documentation on the matter.

How to modify a context from one of its children?

Just to remind you, the Context API allows data storage and makes it accessible to any child component who want to use it. This is valid whatever level of component graph the children is in.

const MyContext = React.createContext()

const MyComponent = () => {
    const count = useContext(MyContext)

    return (
        <div>price: {count}</div>
    )
}

const App = () => (
    <MyContext.Provider value={2}>
        <div>
            <MyComponent />
            <MyComponent />
        </div>
    </MyContext.Provider>
)
Enter fullscreen mode Exit fullscreen mode

If we simplify it as much as we can, contexts are used to pass an information from the top to the bottom of the component tree. How could we do it the other way around? Or how could we modify context without passing the information to the top?

By using functions and closures. As those have simple values like the others, you can store functions in your context. If you store a function that is able to modify the content of the context, every children will be able to use it and to modify it.

To make the values of the context easier to modify, I am going to use the reference from JavaScript (inspired by C, of course).

const MyContext = React.createContext()

const MyComponent = () => {
    const { count } = useContext(MyContext)

    return (
        <div>price: {count}</div>
    )
}

const App = () => {
    const [count] = useState(0)

    return (
        <MyContext.Provider value={{ count }}>
            <div>
                <MyComponent />
                <MyComponent />
            </div>
        </MyContext.Provider>
    )
}
Enter fullscreen mode Exit fullscreen mode

With the previous code, we obtained the same result. We simply moved data storage toward the state of the parent component.

Now we juste have to add a function that modify this state to be able to apply the modification from a child.

const MyContext = React.createContext()

const MyComponent = () => {
    const { count, increment } = useContext(MyContext)

    return (
        <div onClick={increment}>price: {count}</div>
    )
}

const App = () => {
    const [count, updateCount] = useState(0)
    function increment() {
        updateCount(count + 1)
    }

    return (
        <MyContext.Provider value={{ count, increment }}>
            <div>
                <MyComponent />
                <MyComponent />
            </div>
        </MyContext.Provider>
    )
}
Enter fullscreen mode Exit fullscreen mode

Now when the user clicks on the price, it increases by 1 each time.

To sum up, we are storing datas in the state of the component in which we want to use context and we create a function that can modify this state. Then, you pass the state and the function as context values.

It then become possible from the child to get the modification function and to use it to update your context.


To dig a little deeper:

Top comments (0)