引言
在 React 开发中,组件间共享数据是一个非常常见的需求。虽然我们可以通过 props 一层一层地传递数据,但当组件层级较深时,这种方式不仅繁琐,还容易造成“props drilling”问题。为了解决这个问题,React 提供了 Context API,而 useContext 是 React Hooks 中用于更方便地使用 Context 的工具。
📚参考资料
React官方文档: react.dev/reference/r…
什么是 useContext?
useContext 是 React 提供的一个 Hook,用于在函数组件中订阅 React 的 Context。它让你无需显式地通过 props 传递数据,就能访问上层组件提供的值。
语法:
const value = useContext(MyContext);
MyContext是通过React.createContext()创建的上下文对象。value是当前MyContext的值,由离当前组件最近的MyContext.Provider提供。
实例
Context 的基本使用流程:
创建 Context -> 提供 Context -> 消费 Context -> 更新 Context
1.文件结构
2.效果图
3.步骤
3.1 创建 Context
首先,我们需要创建一个 Context。这通常在一个单独的文件中完成,例如 ThemeContext.js。
// src/ThemeContext.js
import { createContext } from "react";
// 创建一个 Context,默认值为 "light"
export const ThemeContext = createContext("light");
3.2 提供 Context 值
接下来,在顶层组件(App.jsx)中使用 ThemeContext.Provider 来提供 Context 值。这样,所有子组件都可以访问到这个值。
// src/App.jsx
import React, { useState } from 'react';
import './App.css';
import Page from './components/Page';
import { ThemeContext } from './ThemeContext';
function App() {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={theme}>
<Page />
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>切换主题</button>
</ThemeContext.Provider>
);
}
export default App;
在
App.jsx中,我们通过toggleTheme函数更新theme状态,由于ThemeContext.Provider的value是响应式的,当状态变化时,所有使用useContext的组件都会自动重新渲染并获取最新的值。
3.3 消费 Context 值
在需要使用 Context 值的组件中,可以通过 useContext Hook 来获取 Context 的值。
// src/components/Child/index.jsx
import React, { useContext } from "react";
import { ThemeContext } from "../../ThemeContext";
const Child = () => {
const theme = useContext(ThemeContext);
return (
<div className={theme}>
Child {theme}
</div>
);
};
export default Child;
3.4 自定义 Hooks 使用 Context
为了更方便地在多个组件中使用同一个 Context,可以创建一个自定义 Hook。
// src/hooks/useTheme.js
import { useContext } from 'react';
import { ThemeContext } from '../ThemeContext';
export function useTheme() {
return useContext(ThemeContext);
}
然后在其他组件中使用这个自定义 Hook。
// src/components/Page/index.jsx
import React from 'react';
import Child from '../Child';
import { useTheme } from '../../hooks/useTheme';
const Page = () => {
const theme = useTheme();
return (
<>
{theme}
<Child />
</>
);
};
export default Page;
4. 总结
- 创建 Context:使用
createContext创建一个 Context 对象。 - 提供 Context 值:使用
Context.Provider组件将值传递给子组件树。 - 消费 Context 值:使用
useContextHook 在函数组件中获取 Context 的值。 - 自定义 Hooks:封装
useContext以简化重复代码。 - 在组件中使用:在需要的地方使用 Context 值,实现跨层级的数据共享。
useContext 的使用技巧
适合使用 useContext 的场景:
- 主题切换
- 用户登录状态
- 多语言支持(i18n)
- 应用配置信息
- 全局状态管理(轻量级)
不建议使用 useContext 的情况:
- 数据只在父子组件间传递(用 props 更清晰)
- 频繁变更的值(建议配合
useReducer或使用状态管理库如 Redux) - 需要高性能优化的场景(频繁更新可能会导致不必要的重渲染)