react組件通信

react組件通信是一個(gè)常用功能扰楼,在做react項(xiàng)目中經(jīng)常遇到

React組件層級(jí)關(guān)系

在了解Reat組件通訊之前,先了解下React層級(jí)關(guān)系。

父子:parent與child1、child2、child1-1堡赔、child2-1

兄弟:child1與child2、child1-1與child1-2...

React組件通訊

組件間通信大體有下面幾種通訊方式:

1.父—>子:使用props
2.子—>父:使用props回調(diào)
3.兄弟組件通信:層層傳遞props设联;發(fā)布者訂閱者模式
4.非嵌套組件間通信:發(fā)布者訂閱者模式善已;redux

1.父—>子
父組件向子組件通信,用到比較多离例。在react中换团,數(shù)據(jù)流動(dòng)是單向的,父組件通過(guò)向子組件傳遞props進(jìn)行通信宫蛆,子組件得到props進(jìn)行相應(yīng)處理艘包。

patrent.js

import React,{Component} from 'react';
import Child1 from "./child1";//子頁(yè)面

export class Parent extends Component {
    state = {
        msg:'parent'
    }
    render(){
        return(
            <div>
            <span>父組件通過(guò)props向子組件通信:</span>
            <Child1 msg={this.state.msg}/>
            </div>
        )
    }
}
export default Parent;

child1.js

import React,{Component} from 'react';

export class child1 extends Component {
    render(){
        return(
            <span>{this.props.msg}</span> //通過(guò)props接收父組件信息
        )
    }
}
export default child1;

如果父組件與子組件之間不止一個(gè)層級(jí),如 parent 與child 耀盗、 child與child1_1 這樣的關(guān)系想虎,parent與child1_1通訊可通過(guò) es6中... 擴(kuò)展運(yùn)算符進(jìn)行通信

export class child1 extends Component {
    render(){
        return(
            <div>
                <span>{this.props.msg}</span><br/>
                <Child1_1 {...this.props}/>//多個(gè)層級(jí)通過(guò)擴(kuò)展運(yùn)算符...
            </div>         
        )
    }
}
export class child1_1 extends Component {
    render(){
        return(
            <span>parent與child1_1通信:{this.props.msg}</span> 
        )
    }
}

2.子—>父
利用回調(diào)函數(shù)。
父組件向子組件傳遞 props 叛拷,只是父組件傳遞的是作用域?yàn)楦附M件自身的函數(shù)舌厨,子組件調(diào)用該函數(shù),將子組件想要傳遞的信息忿薇,作為參數(shù)裙椭,傳遞到父組件的作用域中。
parent.js

export class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            msg: 'parent',
            child2Msg:''
        };
      }

    msgCallback(msg) {
        this.setState({
            child2Msg:msg
        });
    }
    render(){
        return(
            <div>
                <div>
                    <span>父組件通過(guò)props向子組件通信:</span>
                    <Child1 msg={this.state.msg} />
                </div>
                <div>
                    <span>子組件通過(guò)回調(diào)函數(shù)向父組件通信:{this.state.child2Msg}</span><br/>
                    <Child2 msgCallback={child2 => this.msgCallback(child2)} />
                </div>
            </div>
        )
    }
}

child2.js

import React,{Component} from 'react';

export class child2 extends Component {
    render(){
        return(
            <button onClick={()=>this.props.msgCallback("child2")}>child2</button> 
        )
    }
}
export default child2;

對(duì)于層級(jí)比較深的子組件與父組件之間通訊煌恢,參照父組件與子組件通訊骇陈,仍可使用 ... 運(yùn)算符,將父組件的調(diào)用函數(shù)傳遞給子組件

3.兄弟組件通信
A.層層組件傳遞props
對(duì)于沒有直接關(guān)系的兩個(gè)組件瑰抵,就如 child1 與 child2 之間,他們唯一的關(guān)聯(lián)就是擁有相同的父組件parent器联。參考之前父子通訊方式二汛,可以先通過(guò) child1 向 parent 組件進(jìn)行通訊婿崭,再由parent 向 child2 組件進(jìn)行通訊,在這里不貼代碼了肴颊。
不足:當(dāng)Parent 的 state 發(fā)生變化氓栈,會(huì)觸發(fā) Parent 及Parent 的子組件的生命周期,在各個(gè)組件中的 componentDidUpdate 方法均被觸發(fā)婿着。

B.發(fā)布者—訂閱者模式
這種方式可以避免上面的不足授瘦。發(fā)布者發(fā)布事件,訂閱者監(jiān)聽事件并做出反應(yīng)竟宋。
在這里需要一個(gè)事件系統(tǒng)提完,一個(gè)簡(jiǎn)單的事件系統(tǒng)是:

class Event {
    constructor() {
        this.listeners = {};
    }

    on(type, cb, mode) {
        let cbs = this.listeners[type];
        if (!cbs) {
            cbs = [];
        }
        cbs.push(cb);
        this.listeners[type] = cbs;
        return () => {
            this.remove(type, cb);
        };
    }

    emit(type, ...args) {
        const cbs = this.listeners[type];
        if (Array.isArray(cbs)) {
            for (let i = 0; i < cbs.length; i++) {
                const cb = cbs[i];
                if (typeof cb === 'function') {
                    cb(...args);
                }
            }
        }
    }

    remove(type, cb) {
        if (cb) {
            let cbs = this.listeners[type];
            cbs = cbs.filter(eMap => eMap.cb !== cb);
            this.listeners[type] = cbs;
        } else {
            this.listeners[type] = null;
            delete this.listeners[type];
        }
    }
}

export default new Event();

child1頁(yè)面發(fā)布事件

import React,{Component} from 'react';
import Child1_1 from './child1_1';
import Event from '../../utils/event'

export class child1 extends Component {
    componentDidMount() {
        setTimeout(() => {
          // 發(fā)布事件
          Event.emit('child1','child1發(fā)布消息')
        }, 1000);
      }
    render(){
        return(
            <div>
                <span>{this.props.msg}</span><br/>
                <Child1_1 {...this.props}/>
            </div>         
        )
    }
}
export default child1;

child2頁(yè)面接收事件

    componentDidMount() {
        //接收事件
        Event.on('child1', (msg) => {
            this.setState({
                msg
            });
        }
        )
    }

我們可以看到,child1 組件的 componentDidMount 中發(fā)布了事件,child2 組件對(duì)事件做出響應(yīng)丘侠,更新自身 state徒欣,在整個(gè)通訊過(guò)程中,只有 child2 發(fā)出了一次生命周期更新渲染蜗字。
4.redux
Redux是 JavaScript 狀態(tài)容器打肝,是第三方的狀態(tài)管理器,提供可預(yù)測(cè)化的狀態(tài)管理挪捕,是通訊的中間者粗梭。大中型項(xiàng)目可以使用redux,小項(xiàng)目就沒什么必要了级零。redux介紹的東西太多了断医,在這里我就不具體介紹了,感興趣的話妄讯,大家可以去了解下https://www.redux.org.cn/孩锡。

以上若有錯(cuò)誤或考慮不周之處,敬請(qǐng)指正亥贸,謝謝躬窜!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市炕置,隨后出現(xiàn)的幾起案子荣挨,更是在濱河造成了極大的恐慌,老刑警劉巖朴摊,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件默垄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡甚纲,警方通過(guò)查閱死者的電腦和手機(jī)口锭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鹃操,你說(shuō)我怎么就攤上這事韭寸。” “怎么了荆隘?”我有些...
    開封第一講書人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵恩伺,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我椰拒,道長(zhǎng)晶渠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任燃观,我火速辦了婚禮褒脯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仪壮。我一直安慰自己憨颠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開白布积锅。 她就那樣靜靜地躺著爽彤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缚陷。 梳的紋絲不亂的頭發(fā)上适篙,一...
    開封第一講書人閱讀 49,850評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音箫爷,去河邊找鬼嚷节。 笑死,一個(gè)胖子當(dāng)著我的面吹牛虎锚,可吹牛的內(nèi)容都是我干的硫痰。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼窜护,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼效斑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起柱徙,我...
    開封第一講書人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缓屠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后护侮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敌完,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年羊初,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滨溉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖业踏,靈堂內(nèi)的尸體忽然破棺而出禽炬,到底是詐尸還是另有隱情涧卵,我是刑警寧澤勤家,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站柳恐,受9級(jí)特大地震影響伐脖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乐设,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一讼庇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧近尚,春花似錦蠕啄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至格遭,卻和暖如春哈街,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拒迅。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工骚秦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人璧微。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓作箍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親前硫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子胞得,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 1 組件間通信 父組件向子組件通信React規(guī)定了明確的單向數(shù)據(jù)流,利用props將數(shù)據(jù)從父組件傳遞給子組件葱色。故我...
    Dabao123閱讀 937評(píng)論 0 4
  • react是以組合組件的形式組織的递宅,那么組件間是如何傳遞信息的呢? 父組件向子組件通信 parent組件傳給chi...
    DCbryant閱讀 461評(píng)論 0 0
  • 在現(xiàn)代的三大框架中,其中兩個(gè)Vue和React框架办龄,組件間傳值方式有哪些烘绽? 組件間的傳值方式 組件的傳值場(chǎng)景無(wú)外乎...
    mdiep閱讀 1,263評(píng)論 0 0
  • 父子 父子通信(回調(diào)函數(shù))[組件通信] 父?jìng)髯?父組件傳一個(gè)函數(shù)給子組件,子組件在恰當(dāng)?shù)臅r(shí)候調(diào)用 子傳父:1.父組...
    追夢(mèng)的螞蟻閱讀 137評(píng)論 0 0
  • 2018-09-3 周一 今天是什么日子 起床:5:00 就寢:11:00 天氣:晴朗 心情:愉快 紀(jì)念日:升旗的...
    渺塵03閱讀 696評(píng)論 0 0