First, look at this code:
userContext.js
import { createContext, useContext } from "react";
const UserContext = createContext({
user: { name: 'Default User', age: 0 },
setUser: () => {} //we can also pass state here.
});
export const ThemeProvider = ThemeContext.Provider;
export default function useCont() {
return useContext(UserContext);
}
Provide Default Values in createContext
We can provide default values directly when you create a context using React.createContext(). These default values are used only when a component is consuming the context without being wrapped by a Provider. However, it's important to note that if you use a Provider, the values from the Provider will override any default values set in createContext.
const UserContext = createContext({
user: { name: 'Default User', age: 0 },
setUser: () => {} //we can also pass state here.
});
Exporting ContextProvider
Instead of creating a custom Provider
component, you're directly exporting Context.Provider
as ContextProvider
:
export const ThemeProvider = ThemeContext.Provider;
This allows you to use the ThemeProvider anywhere in your app.
Creating a Custom Hook for Easier Consumption
By creating the useCont
hook, you're simplifying the consumption of the context. Instead of writing useContext(UserContext)
every time, you just use useCont()
:
export default function useCont() {
return useContext(UserContext);
}
Now in any component, you can easily access the context.
Benefits of This Structure:
Default Values: You set fallback values in case the Provider is not used.
Reusability: The ThemeProvider and useTheme hook make it easy to use context across your app.
Clean and Simple: It keeps the code modular and separates concerns, making the provider and context consumption easy.
Implementation
App.jsx
import React from 'react';
import { UserProvider, useUser } from './UserContext';
const App = () => {
const { user, setUser } = useUser(); //direct usage of the hook created without need for usercontext and useContect hook.
return (
<UserProvider>//Here we are directly wrapping the children. It can be done even in main.jsx/index.js
<div>
<h1>Name: {user.name}</h1>
<p>Age: {user.age}</p>
<button onClick={() => setUser({ name: 'Jane Doe', age: 25 })}>
Update User
</button>
</div>
</UserProvider>
);
};
export default App;
Top comments (0)