React系列六:Context

React系列151538 阅读0

通常来说,你会通过 props 将信息从父组件传递到子组件。但是,如果你必须通过许多中间组件向下传递 props,或是在你应用中的许多组件需要相同的信息,传递 props 会变的十分冗长和不便。Context 允许父组件向其下层无论多深的任何组件提供信息,而无需通过 props 显式传递。

1. 创建 context,并 将其从一个文件中导出

import { createContext } from 'react';

export const LevelContext = createContext(1);

这里的1是默认值

2. 使用 Context

import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';

const level = useContext(LevelContext);

这里需要用useContext来使用LevelContext

注意!这个示例还不能运行。因为 即使你正在使用 context,但是你还没有提供它。 React 不知道从哪里获取这个 context!

如果你不提供 context,React 会使用你在上一步指定的默认值。在这个例子中,你为 createContext 传入了 1 这个参数,所以 useContext(LevelContext) 会返回 1,

3. 提供 context

用 context provider 包裹起来 以提供 LevelContext

import { LevelContext } from './LevelContext.js';
<LevelContext value={level}>
{children}
</LevelContext>

总结

Context 让你可以编写“适应周围环境”的组件,并且根据 在哪 (或者说 在哪个 context 中)来渲染它们不同的样子。

Context 的工作方式可能会让你想起 CSS 属性继承。在 CSS 中,你可以为一个 手动指定 color: blue,并且其中的任何 DOM 节点,无论多深,都会继承那个颜色,除非中间的其他 DOM 节点用 color: green 来覆盖它。类似地,在 React 中,覆盖来自上层的某些 context 的唯一方法是将子组件包裹到一个提供不同值的 context provider 中。

在 CSS 中,诸如 color 和 background-color 之类的不同属性不会覆盖彼此。你可以设置所有 的 color 为红色,而不会影响 background-color。类似地,不同的 React context 不会覆盖彼此。你通过 createContext() 创建的每个 context 都和其他 context 完全分离,只有使用和提供 那个特定的 context 的组件才会联系在一起。一个组件可以轻松地使用或者提供许多不同的 context。

使用 Context 看起来非常诱人!然而,这也意味着它也太容易被过度使用了。如果你只想把一些 props 传递到多个层级中,这并不意味着你需要把这些信息放到 context 里。

在使用 context 之前,你可以考虑以下几种替代方案:

  1. 从 传递 props 开始。 如果你的组件看起来不起眼,那么通过十几个组件向下传递一堆 props 并不罕见。这有点像是在埋头苦干,但是这样做可以让哪些组件用了哪些数据变得十分清晰!维护你代码的人会很高兴你用 props 让数据流变得更加清晰。
  2. 抽象组件并 将 JSX 作为 children 传递 给它们。 如果你通过很多层不使用该数据的中间组件(并且只会向下传递)来传递数据,这通常意味着你在此过程中忘记了抽象组件。举个例子,你可能想传递一些像 posts 的数据 props 到不会直接使用这个参数的组件,类似 。取而代之的是,让 Layout 把 children 当做一个参数,然后渲染 。这样就减少了定义数据的组件和使用数据的组件之间的层级。

如果这两种方法都不适合你,再考虑使用 context。

评论

发表评论