Context with Hooks
Passing props deep down your component tree is no fun (aka prop drilling). Luckily, the React Context API gives us a way to pass our data through our tree without passing the props at every level.
As an example, let’s say I have some user profile data that I want to use throughout my app.
Start off by creating the Context
to broadcast our data down our child components:
const UserDataContext = React.createContext(null);
I initialised the context with nothing at this stage, but you can also pass existing data.
Next we will create a Provider
component. All the children of this component will be able to access the context.
const UserDataProvider = (props) => {
const [user, setUser] = useState({
firstName: '', lastName: ''
});
return (
<UserDataContext.Provider
value={{ user, setUser }}>
{props.children}
</UserDataContext.Provider>
);
};
When the value prop changes, all the children of the Provider
will re-render.
To access the context values, we can use the useContext
hook on any of the children.
const UserProfileDetail = () => {
const { user } = useContext(UserDataContext);
return (
<>
Firstname: { user.firstName }
Lastname: { user.lastName }
</>
);
};
We initialise the useContext
hook with the context object so that the value can be accessed without the need for prop drilling.
Okay, so we also want to be able to change the context's value. We can access the set function from the context for setUser
and update the user state.
const UserProfile = (props) => {
const { user, setUser } = useContext(UserDataContext);
const [firstName, setFirstName] = useState(user.firstName);
const [lastName, setLastName] = useState(user.lastName);
const handleUpdateUser = () => {
setUser(prevState => ({
...prevState,
firstName,
lastName,
}));
}
return (
<>
<input
value={firstName}
placeholder="Firstname"
onChange={e => setFirstName(e.target.value)}/>
<input
value={lastName}
placeholder="Lastname"
onChange={e => setLastName(e.target.value)} />
<button onClick={handleUpdateUser}>Update user</button>
<h3>User details</h3>
{props.children}
</>
);
};
Cool, now lets throw all the code together and see what we’ve got:
This was a part of the React Hooks series. Checkout the other parts:
What is this React Hooks thing?
State & Effects Hooks
Context Hooks
Reducer Hooks
Custom Hooks
Best Practices