了解 React 上下文 API

有了React的旧背景API,官方建议是开发人员避免使用它,但现在新的背景API是一个一流的公民。

虽然不是用来替代 Redux 或 MobX 等状态管理库,但背景 API 允许在多个组件之间轻松共享全球数据,而无需将其传输为凭证,它解决了一个常见的问题,称为 prop-drilling 问题,在这个问题中,凭证需要被传递到树中的多个组件,以达到需要的组件。

新的 API 特别有用,以提供树上高比例组件所需的数据. 全球偏好,如选定的主题或选定的局部选项,是两个很好的例子。

我们将创建一个简单的Locale环境,为应用程序中的组件提供英语和法语之间的语言偏好,请注意,它只是作为一个简单的示例来展示应用程序的全球偏好,对于React中的真实i18n来说,像 i18next这样的更强大的解决方案更合适。

创建背景

若要创建新的背景,请使用 React 的新的 createContext 函数:

1export const LocaleContext = React.createContext('en');

在这里,我们还将en的默认值输入到文本中,但如果您想要的话,您也可以省略此默认值。

创建背景函数返回提供商和消费者组件。

供应商

提供者组件用于包装需要从文本中访问值的树木中的组件. 在这里,让我们创建一个 LocaleProvider 组件,该组件包装了我们的 LocaleContext 提供商,并提供了一种方法来改变文本中的 ** local** 值:

 1[label context/LocaleContext.js]
 2import React from 'react';
 3
 4export const LocaleContext = React.createContext();
 5
 6class LocaleProvider extends React.Component {
 7  constructor(props) {
 8    super(props);
 9
10    this.changeLocale = () => {
11      this.setState(state => {
12        const newLocale = state.locale === 'en' ? 'fr' : 'en';
13        return {
14          locale: newLocale
15        };
16      });
17    };
18
19    this.state = {
20      locale: 'en',
21      changeLocale: this.changeLocale
22    };
23  }
24
25  render() {
26    return (
27      <LocaleContext.Provider value={this.state}>
28        {this.props.children}
29      </LocaleContext.Provider>
30    );
31  }
32}
33
34export default LocaleProvider;

请注意,LocaleProvider 组件只是我们环境中的 Provider 组件周围的一块薄包裹,而该组件的文本的值是通过值支撑传递给供应商的,然后我们只会渲染 LocaleContext 的孩子。

我们将组件的状态传递为背景值,从那里可使用本地值和更改本地方法来更改该值。

使用供应商

我们可以利用我们的服务提供商在我们的应用程序组件的顶层:

 1[label App.js]
 2import React, { Component } from 'react';
 3
 4import LocaleProvider from './context/LocaleContext';
 5import Greeting from './Greeting';
 6import ToggleLocale from './ToggleLocale';
 7
 8class App extends Component {
 9  render() {
10    return (
11      <LocaleProvider>
12        <Greeting />
13        <ToggleLocale />
14      </LocaleProvider>
15    );
16  }
17}
18
19export default App;

消费者

现在剩下的只是使用消费者组件从文本中访问值。

我们的问候组件看起来像这样:

 1[label Greeting.js]
 2import React from 'react';
 3
 4import { LocaleContext } from './context/LocaleContext';
 5
 6export default () => {
 7  return (
 8    <LocaleContext.Consumer>
 9      {localeVal =>
10        localeVal.locale === 'en' ? <h1>Welcome!</h1> : <h1>Bienvenue!</h1>
11      }
12    </LocaleContext.Consumer>
13  );
14};

我们的ToggleLocale组件看起来像这样:

 1[label ToggleLocale.js]
 2import React from 'react';
 3
 4import { LocaleContext } from './context/LocaleContext';
 5
 6export default () => {
 7  return (
 8    <LocaleContext.Consumer>
 9      {localeVal => (
10        <button onClick={localeVal.changeLocale}>Change language</button>
11      )}
12    </LocaleContext.Consumer>
13  );
14};

消费者组件使用 render prop 模式,并预计一个函数作为其孩子 prop 将从文本中接收值,然后我们可以访问文本中的值,并调用它提供的方法。

有了这个,我们可以将应用程序的问候信息转换为 欢迎欢迎


在我们的示例中,问候和ToggleLocale组件是LocaleProvider组件的直接子女,但它们可以在组件树下方的任何深处,只要使用了该组件的消费者组件,并且提供商位于树上某个地方,它们仍然可以访问全球背景数据。

️ 因此,您应该开始在您的应用程序中使用新的背景API。 有关更多信息,您还可以参阅 官方文件

Published At
Categories with 技术
Tagged with
comments powered by Disqus