DEV Community

Sven Schannak
Sven Schannak

Posted on

Taking advantage of React context und useContext in a function only React App with Hooks

What problem does Context in React solve?

The typical use case for Context in React is passing down user data or the number of current items in a checkout, because you don't really need to load that kind of data every time you rerender a component.

In a common scenario you would pass down the value from the main root, where you have saved the data. This leads to a problem, where you are using some child components just as a proxy to pass down the values. In this case, you would add extra props and dependencies to a component, even if you don't really need them.

import React from 'react';

function UserData({ userName }) {
    return (
        <div>{userName}</div>
    )
}

function Header({ userName }) {
    return (
        <div>
            <h2>Header</h2>
            <UserData userName={userName} />
        </div>
    )
}

export default function MainFn() {
    const [userName, setUserName] = React.useState("Sven");
    React.useEffect(() => {
        // load user data and set username
    }, []);

    return (
        <Header userName={userName} />
    )
}

A better way with React Context

Hooks and React Context to the rescue! With Context we can just set some data from the MainFn and with useContext we can just get the context data into any child elements.

import React from 'react';

const UserContext = React.createContext(
    { username: "", email: "" }
);

function UserData() {
    const context = React.useContext(UserContext);

    return (
        <div>
            {context.username}
        </div>
    )
}

function Header() {
    return (
        <UserData />
    )
}

export default function MainFn() {
    const [username, setUsername] = React.useState("Sven");
    const context = React.useContext(UserContext);

    // copy the origin context to override only necessary objects and not the whole object
    const contextValue = { ...context }
    contextValue["username"] = username;

    return (
        <UserContext.Provider value={contextValue}>
            <Header />
        </UserContext.Provider>
    )
};

Disclaimer

Always think about if you really want to use Context. As you can see, the function for the UserData does not specify any parameter. So you never know what data is needed and where it comes from. By design it is difficult to see which dependencies are needed in a component that uses Context.

Discussion (0)