争怎路由网:是一个主要分享无线路由器安装设置经验的网站,汇总WiFi常见问题的解决方法。

传统组件间通信与React组件间通信的区分比较(代码示例)

时间:2024/6/3作者:未知来源:争怎路由网人气:

[]).forEach(cb => cb(...data)); } } class Child extends EventEimtter { constructor() { super(); // 通过消息接口发布消息 setTimeout(() => { this.pub('update') }, 2000); } } class Parent { constructor() { // 初始化阶段,传入回调函数 this.child = new Child(); // 订阅子组件的消息 this.child.sub('update', function () { console.log('child update') }); } }

Backbone.js就同时支持回调函数和消息接口方式,但React中选择了比较简单的回调函数模式,下面来看一下React的例子

class Child extends Component {
    constructor(props) {
        setTimeout(() => { this.props.cb() }, 2000);
    }
    render() {
        return <p></p>
    }
}

class Parent extends Component {
    render() {
        return <Child cb={() => {console.log('update')}} />
    }
}

爷孙组件

父子组件其实可以算是爷孙组件的一种特例,这里的爷孙组件不光指爷爷和孙子,而是泛指祖先与后代组件通信,可能隔着很多层级,我们已经解决了父子组件通信的问题,根据化归法,很容易得出爷孙组件的答案,那就是层层传递属性么,把爷孙组件通信分解为多个父子组件通信的问题

层层传递的优点是非常简单,用已有知识就能解决,问题是会浪费很多代码,非常繁琐,中间作为桥梁的组件会引入很多不属于自己的属性

在React中,通过context可以让祖先组件直接把属性传递到后代组件,有点类似星际旅行中的虫洞一样,通过context这个特殊的桥梁,可以跨越任意层次向后代组件传递消息

怎么在需要通信的组件之间开启这个虫洞呢?需要双向声明,也就是在祖先组件声明属性,并在后代组件上再次声明属性,然后在祖先组件上放上属性就可以了,就可以在后代组件读取属性了,下面看一个例子

import PropTypes from 'prop-types';

class Child extends Component {
    // 后代组件声明需要读取context上的数据
    static contextTypes = {
        text: PropTypes.string
    }
    render() {
        // 通过this.context 读取context上的数据
        return <p>{this.context.text}</p>
    }
}


class Ancestor extends Component {
    // 祖先组件声明需要放入context上的数据
    static childContextTypes = {
        text: PropTypes.string
    }
    // 祖先组件往context放入数据
    getChildContext() {
        return {text: 'yanhaijing'}
    }
}

context的优点是可以省去层层传递的麻烦,并且通过双向声明控制了数据的可见性,对于层数很多时,不失为一种方案;但缺点也很明显,就像全局变量一样,如果不加节制很容易造成混乱,而且也容易出现重名覆盖的问题

个人的建议是对一些所有组件共享的只读信息可以采用context来传递,比如登录的用户信息等

小贴士:React Router路由就是通过context来传递路由属性的

兄弟组件

如果两个组件是兄弟关系,可以通过父组件作为桥梁,来让两个组件之间通信,这其实就是主模块模式

下面的例子中,两个子组件通过父组件来实现显示数字同步的功能

class Parent extends Component {
    constructor() {
        this.onChange = function (num) {
            this.setState({num})
        }.bind(this);
    }
    render() {
        return (
            <p>
                <Child1 num={this.state.num} onChange={this.onChange}>
                <Child2 num={this.state.num} onChange={this.onChange}>
            </p>
        );
    }
}

主模块模式的优点就是解耦,把两个子组件之间的耦合关系,解耦成子组件和父组件之间的耦合,把分散的东西收集在一起好处非常明显,能带来更好的可维护性和可扩展性

任意组件

任意组件包括上面的三种关系组件,上面三种关系应该优先使用上面介绍的方法,对于任意的两个组件间通信,总共有三种办法,分别是共同祖先法,消息中间件和状态管理

基于我们上面介绍的爷孙组件和兄弟组件,只要找到两个组件的共同祖先,就可以将任意组件之间的通信,转化为任意组件和共同祖先之间的通信,这个方法的好处就是非常简单,已知知识就能搞定,缺点就是上面两种模式缺点的叠加,除了临时方案,不建议使用这种方法

另一种比较常用的方法是消息中间件,就是引入一个全局消息工具,两个组件通过这个全局工具进行通信,这样两个组件间的通信,就通过全局消息媒介完成了

还记得上面介绍的消息基类吗?下面的例子中,组件1和组件2通过全局event进行通信

class EventEimtter {
    constructor() {
        this.eventMap = {};
    }
    sub(name, cb) {
        const eventList = this.eventMap[name] = this.eventMap[name]   

关键词:传统组件间通信与React组件间通信的区分比较(代码示例)




Copyright © 2012-2018 争怎路由网(http://www.zhengzen.com) .All Rights Reserved 网站地图 友情链接

免责声明:本站资源均来自互联网收集 如有侵犯到您利益的地方请及时联系管理删除,敬请见谅!

QQ:1006262270   邮箱:kfyvi376850063@126.com   手机版