嵌套 React Context Provider 并使用 useContext 消费它们有问题吗?
Is nesting React Context Provider and consuming those with useContext a problem?
深度嵌套的 React 上下文提供程序会遇到什么问题?
const AllContextProvider = props => {
return (
<UserProvider>
<ThemeProvider>
<NotifProvider>
<TimelineProvider>
<CertProvider>
<MenusProvider>
{props.children}
</MenusProvider>
</CertProvider>
</TimelineProvider>
</NotifProvider>
</ThemeProvider>
</UserProvider>
);
};
并像这样使用具有上下文依赖性的嵌套提供程序:
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 };
这个上下文依赖总是"re-trigger"菜单上下文提供者吗?
=> 特别是关于无用的重新渲染?
嵌套上下文不会在您的代码中造成任何问题。在上述情况下,如果您在 MenuContext
中订阅 UserContext
,则 MenuContext
只会在 UserContext
更改提供给其提供者的值时重新呈现。但是,除非 MenuContext 更改它传递给 MenuContext Provider
的值,否则订阅 MenuContext
的子项将不会重新呈现,也不会重新呈现其他子项
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);
你可以看到一个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
深度嵌套的 React 上下文提供程序会遇到什么问题?
const AllContextProvider = props => {
return (
<UserProvider>
<ThemeProvider>
<NotifProvider>
<TimelineProvider>
<CertProvider>
<MenusProvider>
{props.children}
</MenusProvider>
</CertProvider>
</TimelineProvider>
</NotifProvider>
</ThemeProvider>
</UserProvider>
);
};
并像这样使用具有上下文依赖性的嵌套提供程序:
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 };
这个上下文依赖总是"re-trigger"菜单上下文提供者吗? => 特别是关于无用的重新渲染?
嵌套上下文不会在您的代码中造成任何问题。在上述情况下,如果您在 MenuContext
中订阅 UserContext
,则 MenuContext
只会在 UserContext
更改提供给其提供者的值时重新呈现。但是,除非 MenuContext 更改它传递给 MenuContext Provider
的值,否则订阅 MenuContext
的子项将不会重新呈现,也不会重新呈现其他子项
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);
你可以看到一个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