Jadual Kandungan
父子组件
爷孙组件
兄弟组件
任意组件
Rumah hujung hadapan web tutorial js 传统组件间通信与React组件间通信的分析对比(代码示例)

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

Sep 17, 2018 pm 03:57 PM
javascript react.js hujung hadapan

本篇文章给大家带来的内容是关于传统组件间通信与React组件间通信的分析对比(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

在React中最小的逻辑单元是组件,组件之间如果有耦合关系就会进行通信,本文将会介绍React中的组件通信的不同方式

通过归纳范,可以将任意组件间的通信归类为四种类型的组件间通信,分别是父子组件,爷孙组件,兄弟组件和任意组件,
需要注意的是前三个也可以算作任意组件的范畴,所以最后一个是万能方法

父子组件

父子组件间的通信分为父组件向子组件通信和子组件向父组件通信两种情况,下面先来介绍父组件向子组件通信,
传统做法分为两种情况,分别是初始化时的参数传递和实例阶段的方法调用,例子如下

class Child {
    constructor(name) {
        // 获取dom引用
        this.$p = document.querySelector('#wp');

        // 初始化时传入name
        this.updateName(name);
    }
    updateName(name) {
        // 对外提供更新的api
        this.name = name;
    
        // 更新dom
        this.$p.innerHTML = name;
    }
}

class Parent {
    constructor() {
        // 初始化阶段
        this.child = new Child('yan');
        
        setTimeout(() => {
            // 实例化阶段
            this.child.updateName('hou');
        }, 2000);
    }
}
Salin selepas log masuk

在React中将两个情况统一处理,全部通过属性来完成,之所以能够这样是因为React在属性更新时会自动重新渲染子组件,
下面的例子中,2秒后子组件会自动重新渲染,并获取新的属性值

class Child extends Component {
    render() {
        return <p>{this.props.name}</p>
    }
}

class Parent extends Component {
    constructor() {
        // 初始化阶段
        this.state = {name: 'yan'};

        setTimeout(() => {
            // 实例化阶段
            this.setState({name: 'hou'})
        }, 2000);
    }
    render() {
        return <Child name={this.state.name} />
    }
}
Salin selepas log masuk

下面来看一下子组件如何向父组件通信,传统做法有两种,一种是回调函数,另一种是为子组件部署消息接口

先来看回调函数的例子,回调函数的优点是非常简单,缺点就是必须在初始化的时候传入,并且不可撤回,并且只能传入一个函数

class Child {
    constructor(cb) {
        // 调用父组件传入的回调函数,发送消息
        setTimeout(() => { cb() }, 2000);
    }
}

class Parent {
    constructor() {
        // 初始化阶段,传入回调函数
        this.child = new Child(function () {
            console.log('child update')
        });
    }
}
Salin selepas log masuk

下面来看看消息接口方法,首先需要一个可以发布和订阅消息的基类,比如下面实现了一个简单的EventEimtter,实际生产中可以直接使用别人写好的类库,比如@jsmini/event,子组件继承消息基类,就有了发布消息的能力,然后父组件订阅子组件的消息,即可实现子组件向父组件通信的功能

消息接口的优点就是可以随处订阅,并且可以多次订阅,还可以取消订阅,缺点是略显麻烦,需要引入消息基类

// 消息接口,订阅发布模式,类似绑定事件,触发事件
class EventEimtter {
    constructor() {
        this.eventMap = {};
    }
    sub(name, cb) {
        const eventList = this.eventMap[name] = this.eventMap[name] || {};
        eventList.push(cb);
    }
    pub(name, ...data) {
        (this.eventMap[name] || []).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')
        });
    }
}
Salin selepas log masuk

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')}} />
    }
}
Salin selepas log masuk

爷孙组件

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

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

在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'}
    }
}
Salin selepas log masuk

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>
        );
    }
}
Salin selepas log masuk

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

任意组件

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

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

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

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

class EventEimtter {
    constructor() {
        this.eventMap = {};
    }
    sub(name, cb) {
        const eventList = this.eventMap[name] = this.eventMap[name] || {};
        eventList.push(cb);
    }
    pub(name, ...data) {
        (this.eventMap[name] || []).forEach(cb => cb(...data));
    }
}

// 全局消息工具
const event = new EventEimtter;

// 一个组件
class Element1 extends Component {
    constructor() {
        // 订阅消息
        event.sub('element2update', () => {console.log('element2 update')});
    }
}

// 另一个组件。
class Element2 extends Component {
    constructor() {
        // 发布消息
        setTimeout(function () { event.pub('element2update') }, 2000)
    }
}
Salin selepas log masuk

消息中间件的模式非常简单,利用了观察者模式,将两个组件之间的耦合解耦成了组件和消息中心+消息名称的耦合,但为了解耦却引入全局消息中心和消息名称,消息中心对组件的侵入性很强,和第三方组件通信不能使用这种方式

小型项目比较适合使用这种方式,但随着项目规模的扩大,达到中等项目以后,消息名字爆炸式增长,消息名字的维护成了棘手的问题,重名概率极大,没有人敢随便删除消息信息,消息的发布者找不到消息订阅者的信息等

其实上面的问题也不是没有解决办法,重名的问题可以通过制定规范,消息命名空间等方式来极大降低冲突,其他问题可以通过把消息名字统一维护到一个文件,通过对消息的中心化管理,可以让很多问题都很容易解决

如果你的项目非常大,上面两种方案都不合适,那你可能需要一个状态管理工具,通过状态管理工具把组件之间的关系,和关系的处理逻辑从组建中抽象出来,并集中化到统一的地方来处理,Redux就是一个非常不错的状态管理工具

除了Redux,还有Mobx,Rematch,reselect等工具,本文不展开介绍,有机会后面单独成文,这些都是用来解决不同问题的,只要根据自己的场景选择合适的工具就好。

Atas ialah kandungan terperinci 传统组件间通信与React组件间通信的分析对比(代码示例). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata Dec 17, 2023 pm 05:30 PM

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

PHP dan Vue: gandingan sempurna alat pembangunan bahagian hadapan PHP dan Vue: gandingan sempurna alat pembangunan bahagian hadapan Mar 16, 2024 pm 12:09 PM

PHP dan Vue: gandingan sempurna alat pembangunan bahagian hadapan Dalam era perkembangan pesat Internet hari ini, pembangunan bahagian hadapan telah menjadi semakin penting. Memandangkan pengguna mempunyai keperluan yang lebih tinggi dan lebih tinggi untuk pengalaman tapak web dan aplikasi, pembangun bahagian hadapan perlu menggunakan alat yang lebih cekap dan fleksibel untuk mencipta antara muka yang responsif dan interaktif. Sebagai dua teknologi penting dalam bidang pembangunan bahagian hadapan, PHP dan Vue.js boleh dianggap sebagai alat yang sempurna apabila digandingkan bersama. Artikel ini akan meneroka gabungan PHP dan Vue, serta contoh kod terperinci untuk membantu pembaca memahami dan menggunakan kedua-dua ini dengan lebih baik.

Soalan yang sering ditanya oleh penemuduga front-end Soalan yang sering ditanya oleh penemuduga front-end Mar 19, 2024 pm 02:24 PM

Dalam temu bual pembangunan bahagian hadapan, soalan lazim merangkumi pelbagai topik, termasuk asas HTML/CSS, asas JavaScript, rangka kerja dan perpustakaan, pengalaman projek, algoritma dan struktur data, pengoptimuman prestasi, permintaan merentas domain, kejuruteraan bahagian hadapan, corak reka bentuk, dan teknologi dan trend baharu. Soalan penemuduga direka bentuk untuk menilai kemahiran teknikal calon, pengalaman projek dan pemahaman tentang trend industri. Oleh itu, calon harus bersedia sepenuhnya dalam bidang ini untuk menunjukkan kebolehan dan kepakaran mereka.

Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Jan 05, 2024 pm 06:08 PM

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Dec 17, 2023 pm 05:13 PM

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Adakah Django bahagian hadapan atau belakang? semaklah! Adakah Django bahagian hadapan atau belakang? semaklah! Jan 19, 2024 am 08:37 AM

Django ialah rangka kerja aplikasi web yang ditulis dalam Python yang menekankan pembangunan pesat dan kaedah bersih. Walaupun Django ialah rangka kerja web, untuk menjawab soalan sama ada Django ialah front-end atau back-end, anda perlu mempunyai pemahaman yang mendalam tentang konsep front-end dan back-end. Bahagian hadapan merujuk kepada antara muka yang pengguna berinteraksi secara langsung, dan bahagian belakang merujuk kepada program bahagian pelayan Mereka berinteraksi dengan data melalui protokol HTTP. Apabila bahagian hadapan dan bahagian belakang dipisahkan, program bahagian hadapan dan bahagian belakang boleh dibangunkan secara bebas untuk melaksanakan logik perniagaan dan kesan interaktif masing-masing, dan pertukaran data.

Apakah ESM modular bahagian hadapan? Apakah ESM modular bahagian hadapan? Feb 25, 2024 am 11:48 AM

Apakah itu ESM bahagian hadapan? Contoh kod khusus diperlukan Dalam pembangunan bahagian hadapan, ESM merujuk kepada ECMAScriptModules, kaedah pembangunan modular berdasarkan spesifikasi ECMAScript. ESM membawa banyak faedah, seperti organisasi kod yang lebih baik, pengasingan antara modul dan kebolehgunaan semula. Artikel ini akan memperkenalkan konsep asas dan penggunaan ESM dan menyediakan beberapa contoh kod khusus. Konsep asas ESM Dalam ESM, kita boleh membahagikan kod kepada berbilang modul, dan setiap modul mendedahkan beberapa antara muka untuk modul lain kepada

Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Jan 05, 2024 pm 01:37 PM

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut

See all articles