最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React组件化-02-组件间通信Context

    正文概述 掘金(徐四)   2021-03-06   521

    React组件化-02-组件间通信Context

    1.React的Context

    Context 提供了⼀个⽆需为每层组件⼿动添加 props,就能在 组件树 间进⾏数据传递的⽅法。

    Context的使用场景:

    Context设计的⽬的是为了共享那些 全局 的数据,例如当前认证的⽤户、主题等。

    ? 下面是通过第①种渲染方式改变按钮主题的例子?:

    1. 通过 React.createContext() 创建一个context 并赋值给变量ThemeContext
    2. ThemeContext 组件中使用ThemeContext.Provider进行包裹,并添加value属性将值传出去
    3. Context的ThemeContext.Provider ----→ ToolBar ----→ ThemeBtn
    4. ThemeBtn中如果是通过 this.context使用value的值 的话,那么在组件中 必须定义一个static自定义属性承载创建的ThemeContext
    5. 组件中使用 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;
    

    ? 下面是通过第②种渲染方式改变按钮主题的例子?:

    1. 前3步,步骤骤和 第①种一样,第4步的时候是使用的 ThemeContext.Consumer 对渲染出口的内容进行包裹。
    2. 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.组件通信高组件装饰器写法:

    将公用的部分抽出去,完成复用,从而完成对代码的瘦身减脂~!

    下面是改造后的代码:

    1. 使用了高阶组件,抽离了公用的部分;
    2. withProvider 为提供者; withConsumer为消费者
    3. {...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;
    

    起源地下载网 » React组件化-02-组件间通信Context

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元