React组件化-02-组件间通信Context
1.React的Context
Context
提供了⼀个⽆需为每层组件⼿动添加 props
,就能在 组件树
间进⾏数据传递的⽅法。
Context的使用场景:
Context设计的⽬的是为了共享那些 全局 的数据,例如当前认证的⽤户、主题等。
? 下面是通过第①种渲染方式改变按钮主题的例子?:
- 通过
React.createContext()
创建一个context
并赋值给变量ThemeContext
- 在
ThemeContext
组件中使用ThemeContext.Provider
进行包裹,并添加value属性
将值传出去 Context的ThemeContext.Provider
----→ToolBar
----→ThemeBtn
ThemeBtn
中如果是通过this.context使用value的值
的话,那么在组件中必须定义一个static自定义属性
去承载创建的ThemeContext
。- 组件中使用
this.context
渲染即可
? 此种渲染方式: 定制当前创建的 上下文对象
,为当前实例的 static静态属性
import React, {Component} from 'react';
import {Button} from "antd";
const ThemeContext = React.createContext();
//按钮Btn
class ThemeBtn extends Component {
constructor(props) {
super(props);
// ? this有个叫context的属性,如果Provider中挂载了value值,那么this.context就会拿到这个值
console.log(this);
}
// ? 如果在组件中想要使用this.context必须先定义一个static静态属性值
static contextType = ThemeContext;
render() {
return (
<Button type={this.context}>初始化按钮</Button>
);
}
}
function Toolbar(props){
return <ThemeBtn> </ThemeBtn>
}
class Context extends Component {
constructor(props) {
super(props);
this.state = {
store :{
type:"primary",
name:"按钮"
}
}
}
render() {
return (
<ThemeContext.Provider value = {this.state.store}>
<Toolbar> </Toolbar>
</ThemeContext.Provider>
);
}
}
export default Context;
? 下面是通过第②种渲染方式改变按钮主题的例子?:
- 前3步,步骤骤和
第①种
一样,第4步的时候是使用的ThemeContext.Consumer
对渲染出口的内容进行包裹。 ThemeContext.Consumer
内部使用通过一个箭头函数
去接收ThemeContext.Provider
提供的value
属性,返回一个jsx
, 然后在页面上完成渲染。
import React, {Component} from 'react';
import {Button} from "antd";
const ThemeContext = React.createContext();
class ThemeBtn extends Component {
constructor(props) {
super(props);
// ? this有个叫context的属性,如果Provider中挂载了value值,那么this.context就会拿到这个值
console.log(this);
}
render() {
return (
<ThemeContext.Consumer>
{
(value)=>{
return (
<Button type={value.type}>初始化按钮</Button>
)
}
}
</ThemeContext.Consumer>
);
}
}
function Toolbar(props){
return <ThemeBtn> </ThemeBtn>
}
class Context extends Component {
constructor(props) {
super(props);
this.state = {
store :{
type:"primary",
name:"按钮"
}
}
}
render() {
return (
<ThemeContext.Provider value = {this.state.store}>
<Toolbar> </Toolbar>
</ThemeContext.Provider>
);
}
}
export default Context;
2.组件通信高组件装饰器写法:
将公用的部分抽出去,完成复用,从而完成对代码的瘦身减脂~!
下面是改造后的代码:
- 使用了高阶组件,抽离了公用的部分;
withProvider
为提供者;withConsumer
为消费者{...this.props}
就是保留原有的props
// ?index.js
import React,{Component} from "react";
const ThemeContext = React.createContext();
// ? 提供者
export const withProvider = Comp => {
return class extends Component{
constructor(props) {
super(props);
//共享的数据
this.state = {
store :{
type:"primary",
name:"按钮"
}
}
}
render() {
return(
<ThemeContext.Provider value={this.state.store}>
<Comp {...this.props}> </Comp>
</ThemeContext.Provider>
)
}
}
}
// ? 消费者
export const withConsumer = Comp => {
return class extends Component{
render() {
return (
<ThemeContext.Consumer>
{
(value)=>{
return (
//? 这里将value作为Comp的props传递下去
<Comp value = {value}> </Comp>
)
}
}
</ThemeContext.Consumer>
)
}
}
}
// ?Conetxt.js
import React, {Component} from 'react';
import {Button} from "antd";
import {withProvider,withConsumer} from "../HOC";
//? 消费者装饰器
@withConsumer
class ThemeBtn extends Component {
constructor(props) {
super(props);
}
render() {
// ? 这里通过this.props来接收
return <Button type={this.props.value.type}>装饰器初始化按钮</Button>
}
}
function Toolbar(props){
return <ThemeBtn> </ThemeBtn>
}
// ? 提供者装饰器
@withProvider
class Context extends Component {
render() {
return <Toolbar> </Toolbar>
}
}
export default Context;
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!