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
相关推荐
拓端研究室44 分钟前
视频讲解:门槛效应模型Threshold Effect分析数字金融指数与消费结构数据
前端·算法
工一木子2 小时前
URL时间戳参数深度解析:缓存破坏与前端优化的前世今生
前端·缓存
半点寒12W3 小时前
微信小程序实现路由拦截的方法
前端
某公司摸鱼前端4 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~4 小时前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程4 小时前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏4 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083165 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头6 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
wen's6 小时前
React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
javascript·react native·react.js