有了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。 有关更多信息,您还可以参阅 官方文件。