上一章ReactJS实战教程请查看:React使用代码分离
上下文允许通过组件树传递数据,而无需在每个级别手动传递props。
在React应用程序中,我们通过props以自顶向下的方式传递数据。有时候,React应用程序中的许多组件都需要某些类型的props,这很不方便。上下文提供了在组件之间传递值的方法,而无需显式地在组件树的每一层传递一个props。
如何使用上下文
在React应用程序中使用React上下文有两个主要步骤:
- 设置上下文提供程序并定义要存储的数据。
- 无论何时需要来自存储的数据,都要使用上下文使用者
何时使用上下文
上下文用于共享可以被认为是React组件树的“全局”数据,并在需要时使用该数据,如当前经过身份验证的用户、主题等。例如,在下面的代码片段中,我们手动通过“主题”props来设置按钮组件的样式。
class App extends React.Component {
render() {
return <Toolbar theme="dark" />;
}
}
function Toolbar(props) {
return (
<div>
<ThemedButton theme={props.theme} />
</div>
);
}
class ThemedButton extends React.Component {
render() {
return <Button theme={this.props.theme} />;
}
}
在上面的代码中,工具栏功能组件接受一个额外的“主题”props并将其传递给ThemedButton。如果应用程序中的每个按钮都需要知道主题,就会变得不方便,因为它需要遍历所有组件。但是使用上下文,我们可以避免通过中间元素传递每个组件的props。
我们可以从下面的例子中理解它。在这里,上下文将一个值传递到组件树中,而不显式地在每个组件中对其进行线程化。
// 为当前主题创建一个默认为“light”的上下文
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
/*使用ContextProvider传递当前主题,这允许每个组件读取它,不管它有多深。在这里,我们将“dark”主题作为当前值传递*/
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// 现在,不需要为每个组件显式地传递主题
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
React上下文API
React Context API是一个组件结构,它使我们能够在应用程序的所有级别之间共享数据。 Context API的主要目的是解决props钻探(也称为“线程”)的问题。 下面给出了React中的Context API。
- React.createContext
- Context.provider
- Context.Consumer
- Class.contextType
React.createContext
它创建了一个上下文对象,当React呈现订阅此上下文对象的组件时,它将从组件树中的匹配提供者读取当前上下文值。
语法
const MyContext = React.createContext(defaultValue);
当组件树中没有匹配的提供程序时,它将返回defaultValue参数,这对于测试组件隔离(单独)而不包装它们非常有帮助。
Context.Provider
每个上下文对象都有一个Provider React组件,该组件允许使用组件订阅上下文更改,它类似一种送货服务。当使用者组件请求某个东西时,它会在上下文中找到它,并将其提供给需要它的地方。
语法
<MyContext.Provider value={/* some value */}>
它接受值prop并传递给作为此Provider的后代的消耗组件。 我们可以将一个提供商与许多消费者联系起来, 可以嵌套上下文提供程序以覆盖组件树中更深的值。 只要提供程序的价值属性发生更改,作为提供程序的后代的所有使用者都将始终重新渲染。,通过使用与Object.is算法相同的算法比较旧值和新值来确定更改。
Context.Consumer
订阅上下文更改的是React组件。它允许我们订阅函数组件中的上下文。它需要将函数作为组件,使用者用于通过提供者请求数据,并在提供者允许时操作中心数据存储。
语法
<MyContext.Consumer>
{value => /* 呈现/渲染基于上下文值的内容 */}
</MyContext.Consumer>
函数组件接收当前上下文值,然后返回一个React节点,传递给函数的值参数将等于组件树中最接近该上下文的提供者的值props。如果此上下文没有提供程序,则value参数将等于传递给createContext()的defaultValue。
Class.contextType
类上的contextType属性,用于分配由response . createcontext()创建的上下文对象,它允许你使用this.context来使用该上下文类型最近的当前值。我们可以在任何组件生命周期方法中引用它,包括render函数。
注意:我们只能使用这个API订阅一个上下文,如果希望使用实验公共类字段的语法,可以使用静态类字段初始化contextType。
React上下文API示例
步骤1:使用以下命令创建一个新的React应用程序。
$ npx create-react-app mycontextapi
步骤2:使用以下命令安装bootstrap CSS框架。
$ npm install react-bootstrap bootstrap --save
步骤3:在src/APP.js文件中添加以下代码片段。
import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
const BtnColorContext = React.createContext('btn btn-darkyellow');
class App extends Component {
render() {
return (
<BtnColorContext.Provider value="btn btn-info">
<Button />
</BtnColorContext.Provider>
);
}
}
function Button(props) {
return (
<div className="container">
<ThemedButton />
</div>
);
}
class ThemedButton extends Component {
static contextType = BtnColorContext;
render() {
return <button className={this.context} >
welcome to srcmini
</button>;
}
}
export default App;
在上面的代码片段中,我们使用React. createcontext()创建了上下文,它返回上下文对象。之后,我们创建了返回Provider组件的包装器组件,然后将所有元素作为子元素添加进来,我们希望从中访问上下文。
评论前必须登录!
注册