useContext 用法全解析:3 个实战案例带你上手!

useContext 是 React 的一个 Hook,用来 在组件树中共享全局数据,避免 props 一层层传递。应用场景有,全局主题(深色 / 浅色)、用户信息(登录状态)、多语言(i18n),配置项、权限控制等。

一. 基本使用步骤

1、创建 context

javascript 复制代码
js
复制编辑
import { createContext } from 'react';

const ThemeContext = createContext('light'); // 默认值是 'light'

2、使用 Provider 提供数据

xml 复制代码
jsx
复制编辑
<ThemeContext.Provider value="dark">
  <App />
</ThemeContext.Provider>

3、在子组件中使用 useContext 获取数据

javascript 复制代码
jsx
复制编辑
import { useContext } from 'react';

const MyComponent = () => {
  const theme = useContext(ThemeContext);
  return <div>当前主题:{theme}</div>;
};

二、完整示例

javascript 复制代码
jsx
复制编辑
// ThemeContext.js
import { createContext } from 'react';
export const ThemeContext = createContext('light');
javascript 复制代码
jsx
复制编辑
// App.js
import React from 'react';
import { ThemeContext } from './ThemeContext';
import Page from './Page';

export default function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Page />
    </ThemeContext.Provider>
  );
}
javascript 复制代码
jsx
复制编辑
// Page.js
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

export default function Page() {
  const theme = useContext(ThemeContext);
  return <div>当前主题是:{theme}</div>;
}

三、补充说明:

特性 说明
createContext() 创建一个 context 对象
Provider 包裹需要共享的组件树,传入 value
useContext(context) 读取 context 的值
默认值 如果没有 Provider,读取的是 createContext 的默认值

四、使用场景


1、按钮权限控制:

第一步:创建权限上下文

javascript 复制代码
js
复制编辑
// AuthContext.js
import { createContext } from 'react';

export const AuthContext = createContext({
  permissions: [], // 权限列表,比如 ['view', 'edit']
});

第二步:创建 AuthProvider 提供权限

javascript 复制代码
jsx
复制编辑
// AuthProvider.js
import React from 'react';
import { AuthContext } from './AuthContext';

// 模拟从后端接口拿到的权限
const mockPermissions = ['view', 'edit'];

export default function AuthProvider({ children }) {
  return (
    <AuthContext.Provider value={{ permissions: mockPermissions }}>
      {children}
    </AuthContext.Provider>
  );
}

第三步:封装一个权限组件 <HasPermission>

javascript 复制代码
jsx
复制编辑
// HasPermission.js
import React, { useContext } from 'react';
import { AuthContext } from './AuthContext';

export default function HasPermission({ children, value }) {
  const { permissions } = useContext(AuthContext);

  if (permissions.includes(value)) {
    return <>{children}</>;
  }
  return null;
}

第四步:在主入口使用 AuthProvider

javascript 复制代码
jsx
复制编辑
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import AuthProvider from './AuthProvider';

ReactDOM.render(
  <AuthProvider>
    <App />
  </AuthProvider>,
  document.getElementById('root')
);

第五步:使用权限组件控制显示内容

javascript 复制代码
jsx
复制编辑
// App.js
import React from 'react';
import HasPermission from './HasPermission';

function App() {
  return (
    <div>
      <h1>操作区</h1>
      <HasPermission value="edit">
        <button>编辑</button>
      </HasPermission>

      <HasPermission value="delete">
        <button>删除</button> {/* 没权限时不会显示 */}
      </HasPermission>
    </div>
  );
}

export default App;

第五步: 总结思路

功能 说明
动态获取权限 从登录接口返回后设置权限列表
多权限判断 value={['edit', 'delete']}(自己扩展支持数组)
权限 hooks 可以封装 useHasPermission() 简化组件调用
配合路由守卫 可以结合 react-router 控制页面访问

2、菜单权限控制:

第一步:菜单定义

arduino 复制代码
js
复制编辑
// menus.js
export const menus = [
  { label: '首页', path: '/', permission: 'view_home' },
  { label: '用户管理', path: '/user', permission: 'manage_user' },
  { label: '设置', path: '/settings', permission: 'view_settings' },
];

第二步:用户权限上下文

javascript 复制代码
js
复制编辑
// AuthContext.js
import { createContext } from 'react';

export const AuthContext = createContext({
  permissions: [],
});
javascript 复制代码
js
复制编辑
// AuthProvider.js
import React from 'react';
import { AuthContext } from './AuthContext';

const userPermissions = ['view_home', 'view_settings']; // 示例权限

export default function AuthProvider({ children }) {
  return (
    <AuthContext.Provider value={{ permissions: userPermissions }}>
      {children}
    </AuthContext.Provider>
  );
}

第三步:菜单组件(根据权限过滤)

javascript 复制代码
jsx
复制编辑
// MenuList.js
import React, { useContext } from 'react';
import { AuthContext } from './AuthContext';
import { menus } from './menus';

export default function MenuList() {
  const { permissions } = useContext(AuthContext);

  const allowedMenus = menus.filter(menu =>
    permissions.includes(menu.permission)
  );

  return (
    <ul>
      {allowedMenus.map(menu => (
        <li key={menu.path}>{menu.label}</li>
      ))}
    </ul>
  );
}

第四步:使用菜单组件

javascript 复制代码
jsx
复制编辑
// App.js
import React from 'react';
import MenuList from './MenuList';

function App() {
  return (
    <div>
      <h2>菜单</h2>
      <MenuList />
    </div>
  );
}

export default App;

第五步: 总结思路

优化点 说明
动态菜单来自接口 支持服务端返回权限和菜单配置
多级菜单 递归判断子菜单权限
UI 框架集成 可配合 Ant Design Vue、Element Plus 做出侧边栏
高亮路由 react-router 结合加 NavLink
相关推荐
尤小小8 分钟前
Vite-SSG 实践:Vue项目预渲染落地完整方案
前端·vue.js
默_笙15 分钟前
🍕 AI 的嘴巴装了水管(上):从"等它说完"到"边说边听"的流式输出指南
前端·javascript
lichenyang45316 分钟前
让 VK 小程序调用 HarmonyOS 原生能力:壳子 SDK 的实现思路
前端
梨想橙汁26 分钟前
Vue3 组合式 API 深度解析:ref/reactive 响应式,计算属性与侦听器
前端·vue.js
暖焰核心27 分钟前
继承全解——继承、默认成员函数、切片、隐藏与虚继承
java·前端·javascript
by组态33 分钟前
Ricon组态系统API参考手册
前端·后端·物联网
前端逗比逗36 分钟前
AI 前端落地实战:SSE 流式输出、断点续传、打字机渲染
前端·webassembly
晴天161 小时前
前端跨域方案解析:JSONP 的原理、实战与演进
前端·状态模式
web打印社区1 小时前
浏览器静默打印?先别装第三个库了
前端·vue.js·chrome·electron·pdf
艾伦野鸽ggg1 小时前
前端异步请求的状态竞争(请求竞态)问题
前端·javascript·axios