createContext
createContext是 React 提供的 API,用于创建一个 Context 对象,用于在组件树中传递数据。
基本语法
JavaScript
import { createContext } from 'react';
const MyContext = createContext(defaultValue);TypeScript
import { createContext } from 'react';
const MyContext = createContext<Type | undefined>(undefined);API 签名
function createContext<T>(defaultValue: T): React.Context<T>;参数:
defaultValue:当组件没有匹配到 Provider 时使用的默认值- 类型:
T(可以是任何类型)
返回值:
React.Context<T>:一个 Context 对象,包含Provider和Consumer属性
使用方式
方式 1:带默认值
// 创建带默认值的 Context
const ThemeContext = createContext('light');
// 如果没有 Provider,使用默认值 'light'
function Component() {
const theme = useContext(ThemeContext); // 'light'
return <div className={theme}>Content</div>;
}方式 2:不带默认值(推荐)
// 创建不带默认值的 Context
const ThemeContext = createContext(undefined);
// 如果没有 Provider,返回 undefined
function Component() {
const theme = useContext(ThemeContext); // undefined
// 需要检查 undefined
return <div className={theme || 'light'}>Content</div>;
}方式 3:TypeScript 类型定义
// 定义类型
interface ThemeContextType {
theme: 'light' | 'dark';
toggleTheme: () => void;
}
// 创建带类型的 Context
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);创建示例
示例 1:简单值
const CountContext = createContext(0);
const ThemeContext = createContext('light');
const UserContext = createContext(null);示例 2:对象值
const UserContext = createContext({
name: '',
email: '',
role: 'user'
});示例 3:函数值
const ApiContext = createContext({
fetch: () => Promise.resolve({}),
post: () => Promise.resolve({})
});示例 4:TypeScript 完整示例
interface AppContextType {
user: { id: number; name: string } | null;
theme: 'light' | 'dark';
setUser: (user: { id: number; name: string } | null) => void;
setTheme: (theme: 'light' | 'dark') => void;
}
const AppContext = createContext<AppContextType | undefined>(undefined);Context 对象属性
创建后的 Context 对象包含两个属性:
Provider
const ThemeContext = createContext('light');
// Provider 用于提供 Context 值
<ThemeContext.Provider value="dark">
<Components />
</ThemeContext.Provider>Consumer
// Consumer 用于在类组件中消费 Context(不常用)
<ThemeContext.Consumer>
{theme => <div className={theme}>Content</div>}
</ThemeContext.Consumer>默认值的作用
何时使用默认值
// 有默认值:组件可以在没有 Provider 时使用默认值
const ThemeContext = createContext('light');
function Component() {
// 即使没有 Provider,也能获取到 'light'
const theme = useContext(ThemeContext);
return <div className={theme}>Content</div>;
}何时不使用默认值
// 无默认值:强制要求使用 Provider(推荐)
const ThemeContext = createContext(undefined);
function Component() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('Component must be used within ThemeProvider');
}
return <div className={context.theme}>Content</div>;
}最佳实践
1. 推荐使用 undefined 作为默认值
// ✅ 推荐:便于错误检查
const ThemeContext = createContext(undefined);
// ❌ 不推荐:可能隐藏错误
const ThemeContext = createContext('light');2. 在 TypeScript 中定义类型
// ✅ 推荐:类型安全
interface ThemeContextType {
theme: string;
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);3. 导出 Context 对象
// contexts/ThemeContext.jsx
export const ThemeContext = createContext(undefined);注意事项
- Context 对象是唯一的:每个
createContext调用都会创建一个新的 Context 对象 - 默认值只在没有 Provider 时使用:如果存在 Provider,即使 value 是
undefined,也不会使用默认值 - Context 值可以是任何类型:字符串、数字、对象、函数等
- TypeScript 类型推断:使用 TypeScript 时,类型会从
defaultValue推断