美文网首页redux
React.withContext和getChildContex

React.withContext和getChildContex

作者: 小龙虾Julian | 来源:发表于2018-07-12 15:13 被阅读0次

    1、React.withContext会执行一个指定上下文信息的回调函数,任何在这个回调函数里面渲染的组件都有这个context访问权限(我对这句话的理解是:为这个组件指定了context)
    (1)情况一:任何想访问context里面的属性的组件都必须显示的指定一个contextTypes的属性,如果没有指定该属性,那么组件通过this.context访问属性将会出错。

    var A = React.createClass({
    
        contextTypes: {
            name: React.PropTypes.string.isRequired,
        },
    
        render: function() {
            return <div>My name is: {this.context.name}</div>;
        }
    });
    
    React.withContext({'name': 'Jonas'}, function () {
        React.render(<A />, document.body);//"My name is: Jonas"
    });
    

    (2)情况二:如果你为一个组件(这里指组件A)指定了context,那么这个组件的子组件(这里指组件B)只要定义了contextTypes,就可以访问到父组件指定的context了。

    var A = React.createClass({
    
        render: function() {
             return <B />;
        }
    });
    
    var B = React.createClass({
        contextTypes: {//这里指定了contextTypes,因此下边的子组件B就可以通过this.context来访问父组件的内容了
            name: React.PropTypes.string
        },
    
        render: function() {
            return <div>My name is: {this.context.name}</div>;
        }
    });
    
    React.withContext({'name': 'Jonas'}, function () {
       React.render(<A />, document.body);
    });
    

    (3)上边情况二中可以看出我们会在文件中引入两个组件,那为了减少文件的引用,我们可以把contextTypes放在minx中,这样用到的组件引用这个minx就可以了。

    var ContextMixin = {
        contextTypes: {
            name: React.PropTypes.string.isRequired
        },
    
        getName: function() {
            return this.context.name;
        }
    };
    
    var A = React.createClass({
        mixins: [ContextMixin],
        render: function() {
             return <div>My name is {this.getName()}</div>;
        }
    });
    
    React.withContext({'name': 'Jonas'}, function () {
        React.render(<A />, document.body);//"My name is: Jonas"
    });
    

    2、getChildContext:与访问context属性需要通过contextTypes指定可访问的属性一样,getChildContext指定的传递给子组件的属性需要先通过childContextTypes来执行,不然会报错。
    (1)情况一:

    // This code *does NOT work* becasue of a missing property from childContextTypes
    var A = React.createClass({
    
        childContextTypes: {//用于说明所传递的数据类型
             // fruit is not specified, and so it will not be sent to the children of A
             name: React.PropTypes.string.isRequired
        },
    
        getChildContext: function() {//getChildContext表示该组件通过context传递数据,该方法返回的对象就是context需要传递的数据
             return {
                 name: "Jonas",
                 fruit: "Banana"
             };
        },
    
        render: function() {
             return <B />;
        }
    });
    
    var B = React.createClass({
    
        contextTypes: {//在子组件中用于说明context接收的数据类型
            fruit: React.PropTypes.string.isRequired
        },
    
        render: function() {
            return <div>My favorite fruit is: {this.context.fruit}</div>;
        }
    });
    
    // Errors: Invariant Violation: A.getChildContext(): key "fruit" is not defined in childContextTypes.
    React.render(<A />, document.body);
    

    (2)情况二:假设应用程序有多层的context。通过withContext和getChildContext指定的context元素都可以被子组件引用。但是子组件是需要通过contextTypes来指定所需要的context元素的。

    var A = React.createClass({
    
        childContextTypes: {
             fruit: React.PropTypes.string.isRequired
        },
    
        getChildContext: function() {
             return { fruit: "Banana" };
        },
    
        render: function() {
             return <B />;
        }
    });
    
    var B = React.createClass({
    
        contextTypes: {
            name: React.PropTypes.string.isRequired,
            fruit: React.PropTypes.string.isRequired
        },
    
        render: function() {
            return <div>My name is: {this.context.name} and my favorite fruit is: {this.context.fruit}</div>;
        }
    });
    
    React.withContext({'name': 'Jonas'}, function () {
        React.render(<A />, document.body);//"My name is: Jonas and my favorite fruit is: Banana"
    });
    

    (3)context是就近引用的,如果你通过withContext指定了context元素,然后又通过getChildContext指定了该元素,该元素的值将会被覆盖。

    var A = React.createClass({
    
        childContextTypes: {
             name: React.PropTypes.string.isRequired
        },
    
        getChildContext: function() {
             return { name: "Sally" };
        },
    
        render: function() {
             return <B />;
        }
    });
    
    var B = React.createClass({
    
        contextTypes: {
            name: React.PropTypes.string.isRequired
        },
    
        render: function() {
            return <div>My name is: {this.context.name}</div>;
        }
    });
    
    React.withContext({'name': 'Jonas'}, function () {
        React.render(<A />, document.body);//"My name is: Sally"
    });
    

    总结:通过context传递属性的方式可以大量减少通过props逐层传递属性的方式,这样可以直接减少组件之间的依赖关系(我之前有一篇文章提到了context可以跨组件传值,大概就是这个意思吧~)

    参考文章:
    React 中使用context实现数据穿越
    react中context学习

    相关文章:
    深入浅出React高阶组件
    React进阶之高阶组件

    相关文章

      网友评论

        本文标题:React.withContext和getChildContex

        本文链接:https://www.haomeiwen.com/subject/kzxrpftx.html