目录前言知识点汇总场景1:使用Provider和Consumer生产和消费数据 文件目录及说明代码文件 ProductContext.js:效果场景2:使用ContextType接收
传统的React应用中,数据通过props属性自上而下(由父组件向子组件)传递,当组件层级数量增多时,在每一层传递props则很繁琐,Context提供了一种新的组件之间共享数据的方式,允许数据隔代传递,而不必显式的通过组件树逐层传递props。
根据官网链接对Context常用的5种使用场景进行了整理,并随文配上完整代码。
使用场景:
以下文件在同级路径:
数据传递路径:
ProviderPage.js ==> MiddlePage.js ==> ConsumerPage.js
import React from 'react';
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 创建1个Context对象并给定默认值,如果没有匹配到Provider,消费组件取Context默认值
export const ProductContext = React.createContext({
name: 'car',
price: 8000,
unit: '$',
});
export const { Provider, Consumer } = ProductContext;
ProviderPage.js:
import React, { PureComponent } from 'react';
import MiddlePage from './MiddlePage';
import { Provider } from './ProductContext';
class ProviderPage extends PureComponent {
state = {
product: {
name: 'plane',
price: 120000,
unit: '$',
},
};
render() {
const { product } = this.state;
return (
<div>
<h1>根组件使用Provider传值,子组件使用Consumer接收</h1>
<Provider value={product}>
<MiddlePage />
</Provider>
{}
{}
</div>
);
}
}
export default ProviderPage;
MiddlePage.js:
import React, { PureComponent } from 'react';
import ConsumerPage from './ConsumerPage';
class MiddlePage extends PureComponent {
render() {
return (
<ConsumerPage />
);
}
}
export default MiddlePage;
ConsumerPage.js:
import React, { PureComponent } from 'react';
import { Consumer } from './ProductContext';
class ConsumerPage extends PureComponent {
render() {
return (
<Consumer>
{context => {
return (
<div>
name:{context.name}
<br />
price:{context.price}
<br />
unit:{context.unit}
</div>
);
}}
</Consumer>
);
}
}
export default ConsumerPage;
可以看到显示的是ProviderPage组件提供的Context值。
FamilyContext.js
import React, { PureComponent } from 'react';
import SonPage from './SonPage';
import { Provider } from './FamilyContext';
class FatherPage extends PureComponent {
state = {
person: {
name: 'Lora',
age: 99,
gender: 'female',
},
};
render() {
const { person } = this.state;
return (
<div>
<h1>使用ContextType消费Context数据</h1>
<Provider value={person}>
<SonPage />
</Provider>
{}
{}
</div>
);
}
}
export default FatherPage;
SonPage.js:和上面的MiddlePage.js一样
import React, { PureComponent } from 'react';
import GrandSonPage from './GrandSonPage'
class SonPage extends PureComponent {
render() {
return (
<GrandSonPage />
);
}
}
export default SonPage;
GrandSonPage.js:使用ContextType
接收数据
import React, { PureComponent } from 'react';
import { FamilyContext } from './FamilyContext';
class GrandSonPage extends PureComponent {
//
static contextType = FamilyContext;
componentDidMount() {
// 使用contexType可以在任意生命周期访问数据
// 使用 this.context 来消费最近 Context 上的那个值
const value = this.context;
console.log(value);
}
render() {
// Context是1个对象,对对象进行解构操作
const { name, age, gender } = this.context;
return (
<div>
name:{name}
<br />
age:{age}
<br />
gender:{gender}
</div>
);
}
}
export default GrandSonPage;
效果
在ProviderPage.js中,被Provider
包裹的组件可以更新的Context数据,没被Provider
包裹的组件只能获取Context默认值。
ProductContext.js
import React from 'react';
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 创建1个Context对象
// 默认值,如果没有匹配到Provider取默认值
export const ProductContext = React.createContext({
name: 'car',
price: 17000,
unit: '$',
});
export const { Provider, Consumer } = ProductContext;
ProviderPage.js
import React, { PureComponent } from 'react';
import { Button, Divider } from 'antd';
import MiddlePage from './MiddlePage';
import { Provider } from './ProductContext';
class ProviderPage extends PureComponent {
state = {
product: {
name: 'plane',
price: 120000,
unit: '$',
},
};
handleChange = () => {
const { product: { name, price, unit } } = this.state;
this.setState({
product: {
name,
price: price + 1,
unit,
},
});
};
render() {
const { product } = this.state;
return (
<div>
<h1>父组件更新Context,被Provider包裹的子组件刷新值,没被包裹的子组件使用Context默认值</h1>
{}
<Provider value={product}>
<MiddlePage />
</Provider>
<Divider />
{}
<MiddlePage />
<Divider />
<Button
onClick={this.handleChange}
type="primary"
>
增加
</Button>
</div>
// {不用Provider,显示Context对象defaultValue
// <MiddlePage />
);
}
}
export default ProviderPage;
MiddlePage.js
import React, { PureComponent } from 'react';
import ConsumerPage from './ConsumerPage';
class MiddlePage extends PureComponent {
render() {
return (
<ConsumerPage />
);
}
}
export default MiddlePage;
ConsumerPage.js
import React, { PureComponent } from 'react';
import { Consumer } from './ProductContext';
class ConsumerPage extends PureComponent {
render() {
return (
<Consumer>
{context => {
return (
<div>
name:{context.name}
<br />
price:{context.price}
<br />
unit:{context.unit}
</div>
);
}}
</Consumer>
);
}
}
export default ConsumerPage;
点击增加按钮,上面的price会增加(使用Context更新值),下面的不变(使用Context默认值)。
ProductContext.js
import React from 'react';
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 创建1个Context对象
// 注意第1个参数是1个object {}
export const ProductContext = React.createContext({
product: {
name: 'car',
price: 8000,
unit: '$',
},
// 通过context传递1个函数,使得consumer组件更新context
handlePrice: () => {
},
},
);
export const { Provider, Consumer } = ProductContext;
ProviderPage.js
import React, { PureComponent } from 'react';
import MiddlePage from './MiddlePage';
import { Provider } from './ProductContext';
class ProviderPage extends PureComponent {
state = {
product: {
name: 'plane',
price: 120000,
unit: '$',
},
// state页包含了更新函数,因此会被传递进context provider
handlePrice: () => this.handlePrice(),
};
handlePrice = () => {
const { product: { name, price, unit } } = this.state;
this.setState({
product: {
name,
price: price + 1,
unit,
},
});
};
render() {
const { product, handlePrice } = this.state;
return (
<div>
<h1>子组件通过context传递的函数更新context,等于在子组件中更新状态</h1>
{}
<Provider value={{ product, handlePrice }}>
<MiddlePage />
</Provider>
{}
{}
</div>
);
}
}
export default ProviderPage;
MiddlePage.js
import React, { PureComponent } from 'react';
import ConsumerPage from './ConsumerPage';
class MiddlePage extends PureComponent {
render() {
return (
<ConsumerPage />
);
}
}
export default MiddlePage;
ConsumerPage.js
import React, { PureComponent } from 'react';
import { Button, Divider } from 'antd';
import { Consumer } from './ProductContext';
class ConsumerPage extends PureComponent {
render() {
return (
<Consumer>
{}
{}
{}
{context => {
return (
<div>
name:{context.product.name}
<br />
price:{context.product.price}
<br />
unit:{context.product.unit}
<Divider />
<Button
onClick={context.handlePrice}
type="primary"
>
增加
</Button>
</div>
);
}}
</Consumer>
);
}
}
export default ConsumerPage;
增加按钮在子组件ConsumerPage.js中定义,Context传递1个函数给子组件,具体的函数实现在父组件ProviderPage.js中,此处感觉还是类似React回调函数,优势就是中间组件MiddlePage不用传递任何props,包括回调函数。
MultiContext.js
import React from 'react';
const SchoolContext = React.createContext({
name: '南师附中',
location: '南京',
});
const StudentContext = React.createContext({
name: 'chengzhu',
age: 17,
});
export { SchoolContext, StudentContext };
ProviderPage.js
import React, { PureComponent } from 'react';
import MiddlePage from './MiddlePage';
import { SchoolContext, StudentContext } from './MultiContext';
class ProviderPage extends PureComponent {
state = {
school: {
name: '清华大学',
location: '北京',
},
student: {
name: '张云',
age: 22,
},
};
render() {
const { school, student } = this.state;
return (
<div>
<h1>消费多个Context</h1>
<SchoolContext.Provider value={school}>
<StudentContext.Provider value={student}>
<MiddlePage />
</StudentContext.Provider>
</SchoolContext.Provider>
</div>
// 不用Provider包裹显示Context中定义的默认值
// <MiddlePage />
);
}
}
export default ProviderPage;
MiddlePage.js
import React, { PureComponent } from 'react';
import ConsumerPage from './ConsumerPage';
class MiddlePage extends PureComponent {
render() {
return (
<ConsumerPage />
);
}
}
export default MiddlePage;
ConsumerPage.js
import React, { PureComponent } from 'react';
import { SchoolContext, StudentContext } from './MultiContext';
class ConsumerPage extends PureComponent {
render() {
return (
<SchoolContext.Consumer>
{school => (
<StudentContext.Consumer>
{student => {
return (
<div>
就读学校: {school.name}
<br />
学校位置: {school.location}
<br />
学生姓名: {student.name}
<br />
学生年龄: {student.age}
</div>
);
}}
</StudentContext.Consumer>
)}
</SchoolContext.Consumer>
);
}
}
export default ConsumerPage;
效果
可以看到传递了2个Context,分别是SchoolContext和StudentContext,子组件ConsumerPage消费了传递进来的2个Context数据。
到此这篇关于React Context用法小结(附完整代码)的文章就介绍到这了,更多相关React Context用法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: React Context用法小结(附完整代码)
本文链接: https://lsjlt.com/news/211234.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0