useContext
1.是什么
useContext 是 React 里"跨组件传递数据"的方案,它解决的问题是:不想一层一层传 props。
// 为什么存在?
// React 默认数据流:父 -> 子
<App>
<Layout>
<Header>
<User />
</Header>
</Layout>
</App>
// 如果 App 有 user 数据,想给 User 组件,通常要一层层 props 传递。
// 可中间的 Layout 和 Header 组件可能不需要 user 数据,还需要传。所以需要 useContext
2.使用方法
创建 Context:
import { createContext } from "react";
const UserContext = createContext();
提供数据:
function App() {
const user = { name: "Tom" };
return (
<UserContext.Provider value={user}>
<Layout />
</UserContext.Provider>
);
}
消费数据:
import { useContext } from "react";
function User() {
const user = useContext(UserContext);
return <h1>{user.name}</h1>;
}
3.高频应用场景
3.1 主题切换
const ThemeContext = createContext();
function App() {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Page />
</ThemeContext.Provider>
);
}
function Button() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
当前主题:{theme}
</button>
);
}
提示
其他使用场景:主题(深色模式,国际化)、用户信息(当前登录用户)、权限(是否管理员)、表单(Form 组件共享状态)
4.不适合的场景
Context 性能不好,因为 Context 更新会导致所有消费者重新 render。
例如:value={{theme, user, count}},如果 count 变化,即使组件只用了 theme,也会 render。
所以不适合高频更新的大状态,例如:大列表,聊天消息流,高频动画状态。否则 render 很多。