createContext

createContext 允许你创建一个上下文,组件可以提供或读取该上下文。

const SomeContext = createContext(defaultValue)

参考

createContext(defaultValue)

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

import { createContext } from 'react';

const ThemeContext = createContext('light');

请在下方查看更多示例。

参数

  • defaultValue:当读取上下文的组件上方树中没有匹配的上下文提供程序时,你希望上下文具有的值。如果你没有任何有意义的默认值,请指定 null。默认值是指“最后手段”的后备。它是静态的,并且永远不会随着时间而改变。

返回值

createContext 返回一个上下文对象。

上下文对象本身不包含任何信息。 它表示其他组件读取或提供的上下文是哪个上下文。通常,你将在上面的组件中使用 SomeContext.Provider 来指定上下文值,并在下面的组件中调用 useContext(SomeContext) 来读取它。上下文对象具有一些属性

  • SomeContext.Provider 允许你向组件提供上下文值。
  • SomeContext.Consumer 是一种替代的且很少使用的读取上下文值的方法。

SomeContext.Provider

将您的组件封装到一个上下文提供程序中,以便为该提供程序内的所有组件指定此上下文的

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

属性

  • value:您想要传递给读取此上下文的所有组件的值,无论它们嵌套多深。上下文值可以是任何类型。在提供程序内部调用 useContext(SomeContext) 的组件将接收其上方最内层对应上下文提供程序的 value

SomeContext.Consumer

useContext 出现之前,有一种较旧的方法来读取上下文。

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

虽然这种旧方法仍然有效,但新编写的代码应该使用 useContext() 来读取上下文:

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

属性

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

用法

创建上下文

上下文允许组件在不显式传递属性的情况下 将信息传递到深处

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

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);
// ...
}

默认情况下,它们接收的值将是您在创建上下文时指定的 默认值。但是,这本身并没有什么用,因为默认值永远不会改变。

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

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

// ...

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

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

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


从文件中导入和导出上下文

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

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

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

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

// 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.Provider value={theme}>
<AuthContext.Provider value={currentUser}>
<Page />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}

这与 导入和导出组件 类似。


故障排除

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

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

const ThemeContext = createContext('light');

此值永远不会改变。React 仅在找不到上方匹配的提供程序时才使用此值作为回退。

要使上下文随时间变化,请 添加状态并将组件封装在上下文提供程序中