useContext

官方文档#

const value = useContext(MyContext);

接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider>value prop 决定。

当组件上层最近的 <MyContext.Provider> 更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext provider 的 context value 值。即使祖先使用 React.memoshouldComponentUpdate,也会在组件本身使用 useContext 时重新渲染。

调用了 useContext 的组件总会在 context 值变化时重新渲染。如果重渲染组件的开销较大,你可以 通过使用 memoization 来优化

note

useContext(MyContext) 相当于 class 组件中的 static contextType = MyContext 或者 <MyContext.Consumer>

useContext(MyContext) 只是让你能够读取 context 的值以及订阅 context 的变化。你仍然需要在上层组件树中使用 <MyContext.Provider> 来为下层组件提供 context。

举个例子#

演示#

源码#

import React, { useContext, useState } from "react";
import "./styles.css";
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext({
theme: themes.light,
setTheme: (theme) => {
console.log("主题:", theme);
}
});
function App() {
const [theme, setTheme] = useState(themes.dark);
const value = {
theme,
setTheme
};
return (
<ThemeContext.Provider value={value}>
<Toolbar />
<div>根组件:{theme.background}</div>
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const { theme, setTheme } = useContext(ThemeContext);
const changeTheme = () => {
setTheme((theme) => {
return theme === themes.dark ? themes.light : themes.dark;
});
};
return (
<div>
子组件:
<button
style={{ background: theme.background, color: theme.foreground }}
onClick={changeTheme}
>
I am styled by theme context!
</button>
</div>
);
}
export default App;