React 中的 useContext:深入理解与实战应用

134 阅读3分钟

引言

在 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.文件结构

image.png

2.效果图

image.png

image.png

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.Providervalue 是响应式的,当状态变化时,所有使用 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 值:使用 useContext Hook 在函数组件中获取 Context 的值。
  • 自定义 Hooks:封装 useContext 以简化重复代码。
  • 在组件中使用:在需要的地方使用 Context 值,实现跨层级的数据共享。

useContext 的使用技巧

适合使用 useContext 的场景

  • 主题切换
  • 用户登录状态
  • 多语言支持(i18n)
  • 应用配置信息
  • 全局状态管理(轻量级)

不建议使用 useContext 的情况:

  • 数据只在父子组件间传递(用 props 更清晰)
  • 频繁变更的值(建议配合 useReducer 或使用状态管理库如 Redux)
  • 需要高性能优化的场景(频繁更新可能会导致不必要的重渲染)