React 上下文
上下文允许通过组件树传递数据,而无需在每个级别手动传递Props。
在React应用程序中,我们以通过Props自上而下的方法。有时,这对于React应用程序中许多组件所需的某些类型的Props很不方便。上下文提供了一种在组件之间传递值的方法,而无需在组件树的每个级别上显式传递Props。
如何使用上下文
有两个主要步骤在React应用程序中使用React上下文:
设置上下文提供程序并定义要存储的数据。
每当您需要存储中的数据时,请使用上下文使用者
何时使用上下文
上下文用于共享可被视为React组件树的"全局"数据,并在需要时使用该数据,例如当前经过身份验证的用户,主题等。例如,在下面的代码段中,我们手动通过"主题"Props来设置Button组件的样式。
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通过中间元素传递。
我们可以从下面的示例中理解它。在这里,上下文将值传递到组件树中,而没有显式地将其穿入每个组件。
// Create a context for the current theme which is "light" as the default.
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
/* Use a ContextProvider to pass the current theme, which allows every component to read it, no matter how deep it is. Here, we are passing the "dark" theme as the current value.*/
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// Now, it is not required to pass the theme down explicitly for every component.
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);
当组件在组件树中没有匹配的Provider时,它将返回defaultValue参数。无需包装它们(单独)对测试组件隔离非常有帮助。
Context.Provider
每个Context对象都有一个Provider React组件,它允许使用组件的组件订阅上下文更改。它充当交付服务。当消费者组件要求某项内容时,它会在上下文中找到它并将其提供给需要的地方。
语法
<MyContext.Provider value={/* some value */}>
它接受值prop并传递给作为此提供程序后代的使用组件。我们可以将一个提供商与许多消费者联系起来。可以嵌套上下文提供程序以覆盖组件树中更深的值。只要提供者的价值支柱发生更改,作为提供者的后代的所有使用者都将始终重新渲染。更改是通过使用与 Object.is 算法相同的算法比较旧值和新值来确定的。
Context.Consumer
React组件订阅了上下文更改。它允许我们在功能组件内订阅上下文。它需要功能作为组件。使用者习惯于通过提供者请求数据,并在提供者允许时操纵中央数据存储。
语法
<MyContext.Consumer>
{value => /* render something which is based on the context value */}
</MyContext.Consumer>
功能组件接收当前上下文值,然后返回React节点。传递给函数的value参数将等于组件树中此上下文的最近提供者的value prop。如果此上下文没有提供程序,则value参数将等于传递给createContext()的defaultValue。
Class.contextType
contextType用于分配由React.createContext()创建的Context对象的类的属性。它允许您使用this.context消耗该Context类型的最接近的当前值。我们可以在任何组件生命周期方法(包括render函数)中引用它。
注意: 我们只能使用此API订阅单个上下文。如果要使用实验性公共类字段的语法,则可以使用静态类字段来初始化contextType。
React Context API示例
Step1 ,使用以下内容创建新的React应用命令。
$ npx create-react-app mycontextapi
Step2 使用以下命令安装引导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 lidihuo
</button>;
}
}
export default App;
在上面的代码片段中,我们使用React.createContext()创建了上下文,该上下文返回Context对象。之后,我们创建了包装器组件,该组件返回了Provider组件,然后将所有元素添加为要从中访问上下文的子元素。
输出:
运行React应用程序时,将显示以下屏幕。