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
相关推荐
人工智能训练师5 分钟前
Ubuntu22.04如何安装新版本的Node.js和npm
linux·运维·前端·人工智能·ubuntu·npm·node.js
Seveny079 分钟前
pnpm相对于npm,yarn的优势
前端·npm·node.js
yddddddy1 小时前
css的基本知识
前端·css
昔人'1 小时前
css `lh`单位
前端·css
围巾哥萧尘3 小时前
美式审美的商务头像照🧣
面试
Nan_Shu_6143 小时前
Web前端面试题(2)
前端
知识分享小能手3 小时前
React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
前端·javascript·vue.js·学习·react.js·react·anti-design-vue
蚂蚁RichLab前端团队4 小时前
🚀🚀🚀 RichLab - 花呗前端团队招贤纳士 - 【转岗/内推/社招】
前端·javascript·人工智能
孩子 你要相信光4 小时前
css之一个元素可以同时应用多个动画效果
前端·css
huangql5204 小时前
npm 发布流程——从创建组件到发布到 npm 仓库
前端·npm·node.js