DEV Community

Cover image for Context in React: Better Approach
Pritpal Singh
Pritpal Singh

Posted on

Context in React: Better Approach

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);
}

Enter fullscreen mode Exit fullscreen mode

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.
});
Enter fullscreen mode Exit fullscreen mode

Exporting ContextProvider

Instead of creating a custom Provider component, you're directly exporting Context.Provider as ContextProvider:

export const ThemeProvider = ThemeContext.Provider;
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

Top comments (0)