createContext

createContext 允许你创建一个 context,组件可以提供或读取它。

const SomeContext = createContext(defaultValue)

参考

🌐 Reference

createContext(defaultValue)

在任何组件外调用 createContext 来创建上下文。

🌐 Call createContext outside of any components to create a context.

import { createContext } from 'react';

const ThemeContext = createContext('light');

查看更多示例。

参数

🌐 Parameters

  • defaultValue:当组件读取上下文时,若其上层的树中没有匹配的上下文提供者,你希望上下文具有的值。如果你没有任何有意义的默认值,请指定 null。默认值旨在作为“最后手段”的回退。它是静态的,且永远不会随时间改变。

返回

🌐 Returns

createContext 返回一个上下文对象。

上下文对象本身不保存任何信息。 它表示其他组件读取或提供的_具体上下文_。通常,你将在上层组件中使用SomeContext来指定上下文值,并在下层组件中调用useContext(SomeContext)来读取它。上下文对象有一些属性:

  • SomeContext 允许你向组件提供上下文值。
  • SomeContext.Consumer 是一种替代且很少使用的读取上下文值的方式。
  • SomeContext.Provider 是在 React 19 之前提供上下文值的传统方式。

SomeContext 提供者

🌐 SomeContext Provider

将你的组件封装到一个上下文提供器中,为内部的所有组件指定此上下文的值:

🌐 Wrap your components into a context provider to specify the value of this context for all components inside:

function App() {
const [theme, setTheme] = useState('light');
// ...
return (
<ThemeContext value={theme}>
<Page />
</ThemeContext>
);
}

注意

从 React 19 开始,你可以将 <SomeContext> 渲染为一个提供者。

🌐 Starting in React 19, you can render <SomeContext> as a provider.

在旧版本的 React 中,使用 <SomeContext.Provider>

🌐 In older versions of React, use <SomeContext.Provider>.

属性

🌐 Props

  • value:你希望传递给在此提供者内部读取该上下文的所有组件的值,无论嵌套多深。上下文值可以是任何类型。在提供者内部调用 useContext(SomeContext) 的组件会接收到其上方最内层对应上下文提供者的 value

SomeContext.Consumer

useContext 出现之前,存在一种更早的读取上下文的方法:

🌐 Before useContext existed, there was an older way to read context:

function Button() {
// 🟡 Legacy way (not recommended)
return (
<ThemeContext.Consumer>
{theme => (
<button className={theme} />
)}
</ThemeContext.Consumer>
);
}

虽然这种较旧的方式仍然可用,新编写的代码应该改为使用 useContext() 来读取上下文:

🌐 Although this older way still works, newly written code should read context with useContext() instead:

function Button() {
// ✅ Recommended way
const theme = useContext(ThemeContext);
return <button className={theme} />;
}

属性

🌐 Props

  • children:一个函数。React 会使用与 useContext() 相同的算法确定的当前上下文值来调用你传入的函数,并渲染你从该函数返回的结果。每当父组件的上下文发生变化时,React 也会重新运行此函数并更新 UI。

用法

🌐 Usage

创建上下文

🌐 Creating context

Context 让组件在不显式传递 props 的情况下 向下传递信息

🌐 Context lets components pass information deep down without explicitly passing props.

在任何组件之外调用 createContext 来创建一个或多个上下文。

🌐 Call createContext outside any components to create one or more contexts.

import { createContext } from 'react';

const ThemeContext = createContext('light');
const AuthContext = createContext(null);

createContext 返回一个 上下文对象。组件可以通过将其传递给 useContext() 来读取上下文:

function Button() {
const theme = useContext(ThemeContext);
// ...
}

function Profile() {
const currentUser = useContext(AuthContext);
// ...
}

默认情况下,它们收到的值将是你在创建上下文时指定的 默认值 。然而,仅凭这一点是不有用的,因为默认值从未改变。

上下文是有用的,因为你可以从你的组件提供其他动态值:

🌐 Context is useful because you can provide other, dynamic values from your components:

function App() {
const [theme, setTheme] = useState('dark');
const [currentUser, setCurrentUser] = useState({ name: 'Taylor' });

// ...

return (
<ThemeContext value={theme}>
<AuthContext value={currentUser}>
<Page />
</AuthContext>
</ThemeContext>
);
}

现在,Page 组件以及其内部的任何组件,无论多么深,都将“看到”传递的上下文值。如果传递的上下文值发生变化,React 也会重新渲染读取该上下文的组件。

🌐 Now the Page component and any components inside it, no matter how deep, will “see” the passed context values. If the passed context values change, React will re-render the components reading the context as well.

阅读更多关于阅读和提供上下文的信息并查看示例。


从文件导入和导出上下文

🌐 Importing and exporting context from a file

通常,不同文件中的组件需要访问相同的上下文。这就是为什么通常会在单独的文件中声明上下文的原因。然后,你可以使用export语句来使上下文对其他文件可用:

🌐 Often, components in different files will need access to the same context. This is why it’s common to declare contexts in a separate file. Then you can use the export statement to make context available for other files:

// Contexts.js
import { createContext } from 'react';

export const ThemeContext = createContext('light');
export const AuthContext = createContext(null);

在其他文件中声明的组件随后可以使用 import 语句来读取或提供此上下文:

🌐 Components declared in other files can then use the import statement to read or provide this context:

// Button.js
import { ThemeContext } from './Contexts.js';

function Button() {
const theme = useContext(ThemeContext);
// ...
}
// App.js
import { ThemeContext, AuthContext } from './Contexts.js';

function App() {
// ...
return (
<ThemeContext value={theme}>
<AuthContext value={currentUser}>
<Page />
</AuthContext>
</ThemeContext>
);
}

这类似于导入和导出组件的方式。

🌐 This works similar to importing and exporting components.


故障排除

🌐 Troubleshooting

我找不到更改上下文值的方法

🌐 I can’t find a way to change the context value

这样的代码指定了默认上下文值:

🌐 Code like this specifies the default context value:

const ThemeContext = createContext('light');

这个值永远不会改变。如果 React 在上方找不到匹配的提供者,它只会将这个值用作回退。

🌐 This value never changes. React only uses this value as a fallback if it can’t find a matching provider above.

为了使上下文随时间变化,添加状态并将组件封装在上下文提供者中。

🌐 To make context change over time, add state and wrap components in a context provider.