【发布时间】:2021-04-14 17:40:33
【问题描述】:
有人可以向我解释为什么下一个代码会重新渲染来自提供者的所有子组件
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext();
const App = () => {
const [theme, setTheme] = useState(false);
console.log("App running");
return (
<ThemeContext.Provider value={{ theme, setTheme }} children={<Child1 />} />
);
};
const Child1 = () => {
console.log("Child1 running");
return (
<div className="child1">
<Child2 />
</div>
);
};
const Child2 = () => {
console.log("Child2 running");
return (
<div className="child2">
<Child3 />
</div>
);
};
const Child3 = () => {
const { theme, setTheme } = useContext(ThemeContext);
console.log("Child3 running");
return (
<div className="child3">
<p>{theme ? "dark" : "light"}</p>
<button onClick={() => setTheme(!theme)}>Change theme</button>
</div>
);
};
export default App;
控制台每次点击按钮,所有组件都会重新渲染
App running
Child1 running
Child2 running
Child3 running
App running
Child1 running
Child2 running
Child3 running
但是如果上下文提供者被包装在一个组件中,如下所示
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext();
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState(false);
console.log("ThemeProvider running");
return (
<ThemeContext.Provider value={{ theme, setTheme }} children={children} />
);
};
const App = () => {
console.log("App running");
return <ThemeProvider children={<Child1 />} />;
};
const Child1 = () => {
console.log("Child1 running");
return (
<div className="child1">
<Child2 />
</div>
);
};
const Child2 = () => {
console.log("Child2 running");
return (
<div className="child2">
<Child3 />
</div>
);
};
const Child3 = () => {
const { theme, setTheme } = useContext(ThemeContext);
console.log("Child3 running");
return (
<div className="child3">
<p>{theme ? "dark" : "light"}</p>
<button onClick={() => setTheme(!theme)}>Change theme</button>
</div>
);
};
export default App;
点击按钮时的控制台
ThemeProvider running
Child3 running
ThemeProvider running
Child3 running
ThemeProvider running
Child3 running
只有使用上下文的组件(和组件上下文提供者)才会重新渲染
react 究竟是如何处理这种情况的
编辑:
react 版本是 17.0.1 顺便说一句
【问题讨论】:
标签: javascript reactjs react-context