Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is nesting React Context Provider and consuming those with useContext a problem?

Tags:

What problem can I encounter with a deep nested React context provider?

const AllContextProvider = props => {
  return (
    <UserProvider>
      <ThemeProvider>
        <NotifProvider>
          <TimelineProvider>
            <CertProvider>
              <MenusProvider>
              {props.children}
              </MenusProvider>
            </CertProvider>
          </TimelineProvider>
        </NotifProvider>
      </ThemeProvider>
    </UserProvider>
  );
};

And consuming those nested providers with a Context dependencie like this :

import React, { useContext } from "react";
import { UserContext } from "./UserContext";
import { useLocalStoragePerUser } from "./useLocalStoragePerUser";

const MenusContext = React.createContext();
const { Provider } = MenusContext;

const MenusProvider = props => {
  // Is this context dependencie always "re-trigger" the Menu Context Provider?
  const { user } = useContext(UserContext);

  // Menus Context
  const [menu, setMenu] = useLocalStoragePerUser( "menus", {
      icons: false,
      labels: true,
      leftMenu: true,
    },
    user
  );

  return (
    <Provider value={{ menu, setMenu}} >
      {props.children}
    </Provider>
  );
};

export { MenusProvider, MenusContext };

Is this context dependencie always "re-trigger" the Menu Context Provider? => especially concerning useless re-renders?

like image 638
Benoit LEGER-DERVILLE Avatar asked Mar 17 '19 09:03

Benoit LEGER-DERVILLE


People also ask

Can you nest context providers React?

Nested context. When you nest a context provider inside a context provider of itself, you can override the previous context. When setting up your React application, you can give your layout sections different names, and use those names within consuming components.

Is context API same as useContext?

The useContext is the React hook, used in context API to consume the context state or object. There are two options for getting the context object. We can get the context object from Context Consumer or useContext Hook.

Can you have multiple contexts in React?

Consuming Multiple Contexts To keep context re-rendering fast, React needs to make each context consumer a separate node in the tree. If two or more context values are often used together, you might want to consider creating your own render prop component that provides both.

Why do we need useContext in React?

Context provides a way to pass data or state through the component tree without having to pass props down manually through each nested component.


1 Answers

Having nested Contexts will not cause any issues in your code. In the above case if you subscribe to UserContext in MenuContext, the MenuContext will only re-render when the UserContext has changed the value supplied to its provider. However unless the MenuContext changes the value it passes to the MenuContext Provider its children who are subscribing to MenuContext will not re-render and also no other children will be re-rendered

import React from "react";
import ReactDOM from "react-dom";
import { UserProvider } from "./UserProvider";
import { ThemeProvider } from "./ThemeProvider";
import { MenusProvider } from "./MenuProvider";

import "./styles.css";
function Child() {
  console.log("Child render");
  return <div>Menus Child</div>;
}
function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <UserProvider>
        <ThemeProvider>
          <MenusProvider>
            <Child />
          </MenusProvider>
        </ThemeProvider>
      </UserProvider>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

You can see a DEMO in the codeSandbox here

P.S. However you must make sure that you are not creating a new object while passing the value to a Provider otherwise everytime the Provider re-renders all children which subscribe to its context will re-render

like image 150
Shubham Khatri Avatar answered Sep 21 '22 03:09

Shubham Khatri