![](https://img.haomeiwen.com/i8207483/c20175c8a359f026.png)
纵观前端框架,在国内还是 vue 和 react 是比较受欢迎的。angular 较他们要显得稍弱一些。我接触 react 自认为比较早,但是还没有实际将其应用到大型应用中的经验。今天我们看一看 react,最近也是重新将其捡起,有说的不对地方还希望大家指正。
今天我们来谈一谈 context ,我们知道 react 中数据流是单向传递的,如果数据流从顶层一路流到底层是比较耗时耗力的。我们通过实例来进行说明问题所在。
import React, { Component } from 'react';
class Greeting extends Component{
render(){
return(
<div>
<p>zidea</p>
</div>
)
}
}
export default Greeting;
import React from 'react';
import './App.css';
import Greeting from './Context/Greeting';
// const Extended
function App() {
return (
<div>
<Greeting/>
</div>
);
}
export default App;
我们使用 create-react-app 创建应用后对代码进行调整,删除一些我们不需要的模板代码。
state = {
name:'zidea',
age:35,
married:true
}
在 Greeting 定义 state 对象,包含数据,然后创建一个 Person 组件,这个组件将会消费 Greeting 组件中 state 数据。
class Person extends Component{
render(){
return (
<div className="person">
<p>i am zidea</p>
</div>
)
}
}
class Greeting extends Component{
state = {
name:'zidea',
age:35,
married:true
}
render(){
return(
<div>
<Person/>
</div>
)
}
}
render(){
return(
<div>
<Person name={this.state.name}/>
</div>
)
}
可以通过 prop 将数据传递给 Person,然后在 Person 组件中通过 this.props.name
来消费 name 传递过来值。
class Person extends Component{
render(){
return (
<div className="person">
<p>i am {this.props.name}</p>
</div>
)
}
}
创建中间组件 Family 来包裹 Person 组件。随后我们数据传递需要经过 Family 组件传递给 Person 组件。
const Family = (props) => (
<div className="family">
<Person/>
</div>
)
class Greeting extends Component{
state = {
name:'zidea',
age:35,
married:true
}
render(){
return(
<div>
<Family/>
</div>
)
}
}
如果再多了一层 Family ,我们在 Greeting 定义数据需要经过 Family 组件传递给 Person 组件。
const Family = (props) => (
<div className="family">
<Person name={props.name}/>
</div>
)
class Person extends Component{
render(){
return (
<div className="person">
<p>i am {this.props.name}</p>
</div>
)
}
}
class Greeting extends Component{
state = {
name:'zidea',
age:35,
married:true
}
render(){
return(
<div>
<Family name={this.state.name}/>
</div>
)
}
}
这样问题就是我们在顶层 Greeting 定义组件中定义数据需要层层传递给这些数据消费者 Person,中间经过了中间商 Family,其实我们希望厂家直接面对消费者,没有中间商。让我想起了淘宝。其实这里还好中间只有一层,在实际开发中中间层组件可能会有很多,所以我们就需要 context 来消除数据传递的中间层组件。
创建 React.createContext() 创建一个 Context 作为上下文对象,
const MContext = React.createContext();
//创建 provider
class MProvider extends Component{
state = {
name:'zidea',
age:35,
married:true
}
render(){
return(
<MContext.Provider>
{this.props.children}
</MContext.Provider>
)
}
}
然后创建 MProvider 组件来在 Context 中提供了
- provider 提供者
- consumer 消费者
Context 类似淘宝提供一个平台,让厂家(Provider)和消费者(Consumer)可以直接面对面。
需要用 MContext.Provider 包裹我们组件
import React, { Component } from 'react';
const MContext = React.createContext();
//创建 provider
class MProvider extends Component{
state = {
name:'zidea',
age:35,
married:true
}
render(){
return(
<MContext.Provider>
{this.props.children}
</MContext.Provider>
)
}
}
const Family = (props) => (
<div className="family">
<Person/>
</div>
)
class Person extends Component{
render(){
return (
<div className="person">
<p>this is wrapped by provider</p>
</div>
)
}
}
class Greeting extends Component{
render(){
return(
<MProvider>
<div>
<Family/>
</div>
</MProvider>
)
}
}
export default Greeting;
我们去掉通过 props 来传递数据的逻辑,然后 MContext.Provider 中定义属性 value 我们的值是通过 provider 的 value 属性传递给 consumer 的。
render(){
return(
<MContext.Provider value="zidea">
{this.props.children}
</MContext.Provider>
)
}
class Person extends Component{
render(){
return (
<div className="person">
<MContext.Consumer>
{(context)=>(
<p>I am {context}</p>
)}
</MContext.Consumer>
</div>
)
}
}
值已经从 Provider 传递出来了,那么我们如何在 Person 中接收数据呢,这时候需要用到 Context 的 Consumer 组件在组件我们可以通过自定义一个函数来接收 context 这个 context 就负责接收 provider 中 value 的值。
以此来实现数据在 Provider 和 Consumer 间传递。除了传递数据我们也可以传递行为。
class MProvider extends Component{
state = {
name:'zidea',
age:35,
married:true
}
render(){
return(
<MContext.Provider value={{
state: this.state
}}>
{this.props.children}
</MContext.Provider>
)
}
}
class Person extends Component{
render(){
return (
<div className="person">
<MContext.Consumer>
{(context)=>(
<React.Fragment>
<p>I am {context.state.name}</p>
<p>I am {context.state.age} year old</p>
</React.Fragment>
)}
</MContext.Consumer>
</div>
)
}
}
class MProvider extends Component{
state = {
name:'zidea',
age:35,
married:true,
level:5
}
render(){
return(
<MContext.Provider value={{
state: this.state,
changeMarryState : (b) => this.setState({
married:b
}),
incrementLevel :() => this.setState({
level:this.state.level + 1
})
}}>
{this.props.children}
</MContext.Provider>
)
}
}
const Family = (props) => (
<div className="family">
<Person/>
</div>
)
class Person extends Component{
render(){
return (
<div className="person">
<MContext.Consumer>
{(context)=>(
<React.Fragment>
<p>I am {context.state.name}</p>
<p>I am {context.state.age} year old</p>
<p>I am {context.state.level} level</p>
<button onClick={context.incrementLevel} >increment level</button>
</React.Fragment>
)}
</MContext.Consumer>
</div>
)
}
}
![](https://img.haomeiwen.com/i8207483/0607293c909bd948.png)
网友评论