目录
[1. createContext 的作用](#1. createContext 的作用)
[2. useContext 的作用](#2. useContext 的作用)
[二、在 Ant Design Pro v6 中的实现步骤](#二、在 Ant Design Pro v6 中的实现步骤)
[1. 封装 Provider 组件](#1. 封装 Provider 组件)
[2. 集成到全局布局](#2. 集成到全局布局)
[3. 组件中消费状态](#3. 组件中消费状态)
[1. 避免无效渲染](#1. 避免无效渲染)
[2. 自定义 Hook 封装](#2. 自定义 Hook 封装)
[1. 典型应用场景](#1. 典型应用场景)
[2. 关键注意事项](#2. 关键注意事项)
在 Ant Design Pro v6(基于 Umi 4 + React 18+)与 TypeScript 中,createContext
和 useContext
是管理跨组件状态的核心工具。以下是结合最佳实践的系统指南:
一、核心概念与流程
1. createContext
的作用
创建上下文对象,包含 Provider
(提供数据)和 Consumer
(消费数据,已被 useContext
替代)。
-
TypeScript 强类型定义 :避免运行时错误,明确上下文结构:
// src/contexts/UserContext.ts import { createContext } from 'react'; interface UserContextType { name: string; role: 'admin' | 'user'; setUser: (user: Partial<UserContextType>) => void; } export const UserContext = createContext<UserContextType | null>(null);
2. useContext
的作用
在函数组件中消费上下文值,避免逐层传递 props:
const userContext = useContext(UserContext);
if (!userContext) throw new Error('未在 Provider 内使用!');
return userContext;
二、在 Ant Design Pro v6 中的实现步骤
1. 封装 Provider 组件
在 /src/contexts
目录下创建 Provider,结合 useState
或 useReducer
管理状态:
// src/contexts/UserProvider.tsx
import { ReactNode, useState } from 'react';
import { UserContext } from './UserContext';
export default ({ children }: { children: ReactNode }) => {
const [user, setUser] = useState({ name: '', role: 'user' });
const contextValue = {
...user,
setUser: (updates: Partial<UserContextType>) =>
setUser(prev => ({ ...prev, ...updates }))
};
return (
<UserContext.Provider value={contextValue}>
{children}
</UserContext.Provider>
);
};
2. 集成到全局布局
在 src/app.tsx
中包裹全局组件,确保所有页面可访问上下文:
// src/app.tsx
import UserProvider from '@/contexts/UserProvider';
export function rootContainer(container: ReactNode) {
return <UserProvider>{container}</UserProvider>;
}
3. 组件中消费状态
直接通过 useContext
获取数据或更新函数:
// src/pages/Profile/index.tsx
import { UserContext } from '@/contexts/UserContext';
export default () => {
const { name, setUser } = useContext(UserContext)!;
return (
<Button onClick={() => setUser({ name: 'Admin' })}>
更新用户:{name}
</Button>
);
};
三、性能优化技巧
1. 避免无效渲染
-
拆分上下文 :将频繁变更的状态(如用户输入)与静态数据(如配置)分离。
const UserConfigContext = createContext<ConfigType>(null!); const UserStateContext = createContext<StateType>(null!);
-
缓存
value
对象 :使用useMemo
减少重渲染:const contextValue = useMemo(() => ({ user, setUser }), [user]);
2. 自定义 Hook 封装
提供类型安全提示,简化调用:
// src/hooks/useUser.ts
export default () => {
const context = useContext(UserContext);
if (!context) throw new Error('UserContext 未初始化');
return context;
};
四、常见场景与避坑指南
1. 典型应用场景
- 用户身份认证状态
- 主题切换(深色/浅色模式)
- 多语言国际化(结合
umi-plugin-locale
) - 全局弹窗/通知控制
2. 关键注意事项
- 默认值问题 :未包裹
Provider
时返回createContext
的默认值,需做好错误处理。 - 嵌套顺序 :内层
Provider
会覆盖外层同名Context
。 - 异步更新 :在
useEffect
中更新上下文时,需考虑依赖项避免死循环。
五、完整案例:主题切换实现
// 1. 定义主题上下文
const ThemeContext = createContext<{
theme: 'light' | 'dark';
toggleTheme: () => void;
} | null>(null);
// 2. 创建 Provider
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
const toggleTheme = () => setTheme(t => t === 'light' ? 'dark' : 'light');
const value = useMemo(() => ({ theme, toggleTheme }), [theme]);
return (
<ThemeContext.Provider value={value}>
{children}
</ThemeContext.Provider>
);
};
// 3. 在组件中使用
const ThemeButton = () => {
const { theme, toggleTheme } = useContext(ThemeContext)!;
return (
<Button onClick={toggleTheme}>
当前主题:{theme}
</Button>
);
};
总结
在 Ant Design Pro v6 + TypeScript 技术栈中:
- 强类型定义是基础,避免空值错误;
- Provider 全局挂载确保跨组件共享状态;
- 性能优化 优先考虑上下文拆分与
useMemo
; - 自定义 Hook 提升代码复用率与可维护性。
通过上下文管理轻量级全局状态,可减少对 Redux 的依赖,保持项目简洁性。