1. 程式人生 > >【轉】React 元件間通訊

【轉】React 元件間通訊

原文連結

說 React 元件間通訊之前,我們先來討論一下 React 元件究竟有多少種層級間的關係。假設我們開發的專案是一個純 React 的專案,那我們專案應該有如下類似的關係:

父子:Parent 與 Child_1、Child_2、Child_1_1、Child_1_2、Child_2_1

兄弟:Child_1 與 Child_2、Child_1_1 與 Child_2、etc.

針對這些關係,我們將來好好討論一下這些關係間的通訊方式。

(在 React 中,React 元件之間的關係為從屬關係,與 DOM 元素之間的父子關係有所不同,下面只是為了說明方便,將 React 元件的關係類比成父子關係進行闡述)

父元件向子元件通訊

通訊是單向的,資料必須是由一方傳到另一方。在 React 中,父元件可以向子元件通過傳 props 的方式,向子元件進行通訊。

class Parent extends Component{
  state = {
    msg: 'start'
  };

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        msg: 'end'
      });
    }, 1000);
  }

  render() {
    return <Child_1
msg={this.state.msg} />
;
} } class Child_1 extends Component{ render() { return <p>{this.props.msg}</p> } }

如果父元件與子元件之間不止一個層級,如 Parent 與 Child_1_1 這樣的關係,可通過 ... 運算子(Object 剩餘和展開屬性),將父元件的資訊,以更簡潔的方式傳遞給更深層級的子元件。通過這種方式,不用考慮效能的問題,通過 babel 轉義後的 ... 運算子效能和原生的一致,且上級元件 props 與 state 的改變,會導致元件本身及其子元件的生命週期改變,

// 通過 ... 運算子 向 Child_1_1 傳遞 Parent 元件的資訊
class Child_1 extends Component{
  render() {
    return <div>
      <p>{this.props.msg}</p>
      <Child_1_1 {...this.props}/>
    </div>
  }
}

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

子元件向父元件通訊

在上一個例子中,父元件可以通過傳遞 props 的方式,自頂而下向子元件進行通訊。而子元件向父元件通訊,同樣也需要父元件向子元件傳遞 props 進行通訊,只是父元件傳遞的,是作用域為父元件自身的函式,子元件呼叫該函式,將子元件想要傳遞的資訊,作為引數,傳遞到父元件的作用域中。

class Parent extends Component{
  state = {
    msg: 'start'
  };

  transferMsg(msg) {
    this.setState({
      msg
    });
  }

  render() {
    return <div>
        <p>child msg: {this.state.msg}</p>
        <Child_1 transferMsg = {msg => this.transferMsg(msg)} />
      </div>;
  }
}

class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      this.props.transferMsg('end')
    }, 1000);
  }

  render() {
    return <div>
      <p>child_1 component</p>
    </div>
  }
}

在上面的例子中,我們使用了 箭頭函式,將父元件的 transferMsg 函式通過 props 傳遞給子元件,得益於箭頭函式,保證子元件在呼叫 transferMsg 函式時,其內部 this 仍指向父元件。

當然,對於層級比較深的子元件與父元件之間的通訊,仍可使用 ... 運算子,將父元件的呼叫函式傳遞給子元件,具體方法和上面的例子類似。

兄弟元件間通訊

對於沒有直接關聯關係的兩個節點,就如 Child_1 與 Child_2 之間的關係,他們唯一的關聯點,就是擁有相同的父元件。參考之前介紹的兩種關係的通訊方式,如果我們向由 Child_1 向 Child_2 進行通訊,我們可以先通過 Child_1 向 Parent 元件進行通訊,再由 Parent 向 Child_2 元件進行通訊,所以有以下程式碼。

class Parent extends Component{
  state = {
    msg: 'start'
  };

  transferMsg(msg) {
    this.setState({
      msg
    });
  }

  componentDidUpdate() {
    console.log('Parent update');
  }

  render() {
    return (
      <div>
        <Child_1 transferMsg = {msg => this.transferMsg(msg)} />
        <Child_2 msg = {this.state.msg} />
      </div>
    );
  }
}

class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      this.props.transferMsg('end')
    }, 1000);
  }

  componentDidUpdate() {
    console.log('Child_1 update');
  }

  render() {
    return <div>
      <p>child_1 component</p>
    </div>
  }
}

class Child_2 extends Component{
  componentDidUpdate() {
    console.log('Child_2 update');
  }

  render() {
    return <div>
      <p>child_2 component: {this.props.msg}</p>
      <Child_2_1 />
    </div>
  }
}

class Child_2_1 extends Component{
  componentDidUpdate() {
    console.log('Child_2_1 update');
  }

  render() {
    return <div>
      <p>child_2_1 component</p>
    </div>
  }
}

然而,這個方法有一個問題,由於 Parent 的 state 發生變化,會觸發 Parent 及從屬於 Parent 的子元件的生命週期,所以我們在控制檯中可以看到,在各個元件中的 componentDidUpdate 方法均被觸發。

有沒有更好的解決方式來進行兄弟元件間的通訊,甚至是父子元件層級較深的通訊的呢?

觀察者模式

在傳統的前端解耦方面,觀察者模式作為比較常見一種設計模式,大量使用在各種框架類庫的設計當中。即使我們在寫 React,在寫 JSX,我們核心的部分還是 JavaScript。

觀察者模式也叫 釋出者-訂閱者模式,釋出者釋出事件,訂閱者監聽事件並做出反應,對於上面的程式碼,我們引入一個小模組,使用觀察者模式進行改造。

import eventProxy from '../eventProxy'

class Parent extends Component{
  render() {
    return (
      <div>
        <Child_1/>
        <Child_2/>
      </div>
    );
  }
}
// componentDidUpdate 與 render 方法與上例一致
class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      // 釋出 msg 事件

            
           

相關推薦

React 元件通訊

原文連結 說 React 元件間通訊之前,我們先來討論一下 React 元件究竟有多少種層級間的關係。假設我們開發的專案是一個純 React 的專案,那我們專案應該有如下類似的關係: 父子:Parent 與 Child_1、Child_2、Ch

react-native-wechat元件使用介紹

react-native-wechat 具有微信 登入,分享,收藏(v1.9.9+) 和支付的功能,適合iOS/Android 雙平臺使用 安裝 react-native-wechat //npm 安裝 npm install react-native-wechat --save //yarn 安裝 y

物聯網常見通訊協議

轉載地址:https://www.jianshu.com/p/f3f1a35f64cc 1  “通訊”與“通訊”傻傻分得清 傳統意義上的“通訊”主要指電話、電報、電傳。通訊的“訊”指訊息(Message),媒體訊息通過通訊網路從一端傳遞到另外一端。媒體訊息的

解密傳統元件通訊React元件通訊

在React中最小的邏輯單元是元件,元件之間如果有耦合關係就會進行通訊,本文將會介紹React中的元件通訊的不同方式 通過歸納範,可以將任意元件間的通訊歸類為四種類型的元件間通訊,分別是父子元件,爺孫元件,兄弟元件和任意元件,需要注意的是前三個也可以算作任意元件的範

React元件通訊(父=>子)(子=>父)(子=>爺)(刪除指定下標的資料)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-

LinuxLinux程序通訊之訊息佇列

1、訊息佇列概念引入    訊息佇列提供了一個從一個程序向另外一個程序傳送一塊資料的方法每個資料塊都被認為是有一個型別,接收者程序接收的資料塊可以有不同的型別值訊息佇列也有管道一樣的不足,就是每個訊息的最大長度是有上限的(MSG

React 常用面試題目與分析

作者:王下邀月熊 連結:https://zhuanlan.zhihu.com/p/24856035 來源:知乎 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 呼叫 setState 之後發生了什麼? 在程式碼中呼叫setState函式之後,React 會將傳入的引數物件與元件當前的狀態

React 元件通訊

在經歷了許多的html+css+js的傳統網頁製作之後,最近開始上手react了。學了一點語法之後就開始了react的專案, 然而事情不總是一帆風順的。剛上手的時候,專案的進度就是一團糟。各種迷之bug紛至沓來,在這裡真的要提醒諸位,在寫react es6語法

React Native中ES5 ES6寫法對照

箭頭 dcom 卸載 compose 添加 sem this blank topic   很多React Native的初學者都被ES6的問題迷惑:各路大神都建議我們直接學習ES6的語法(class Foo extends React.Component),然而網上搜到的很

React、Vue直接訪問url地址,訪問出錯報404

直接 .so 開發 跳轉 otf dcom outer ons tac 部署完成後,訪問沒問題,從頁面中點擊跳轉也沒問題,但是只要點擊刷新或通過瀏覽器地址欄回車,就會出現404現象!在本地開發中是沒有這個問題的,調試的時候一切都是正常的 直接訪問地址,便會出現404

JAVA 並發性和多線程 -- 讀感 (二 線程通訊,共享內存的機制)

instance bar log 通信 java t 是的 復制代碼 ott bus 原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 參考文章:http://ifeve.com/java-concurrenc

程序/執行緒同步的方式和機制,程序通訊

(轉自:https://www.cnblogs.com/virusolf/p/5331946.html) 一、程序/執行緒間同步機制。 臨界區、互斥區、事件、訊號量四種方式臨界區(Critical Section)、互斥量(Mutex)、訊號量(Semaphore)、事件(Event)的區別

React歸納篇(十)元件通訊方式之Redux | UI元件AntDesign | Redux-react

react-router4 react-router概覽 1、react的一個外掛庫 2、專門用於實現一個SPA應用 3、基於react的專案都會用到該庫 SPA 1、點選頁面中的連結不會重新整理頁面,本身也不會向伺服器傳送請求 2、點選路由連結時,只會發

程序通訊的方式(8種)

程序間通訊的方式——訊號、管道、訊息佇列、共享記憶體 多程序: 首先,先來講一下fork之後,發生了什麼事情。 由fork建立的新程序被稱為子程序(child process)。該函式被呼叫一次,但返回兩次。兩次返回的區別是子程序的返回值是0,而父程序的返回值則是新程序(子程序)的程序

Linux程序通訊方式和原理

程序的概念 程序是作業系統的概念,每當我們執行一個程式時,對於作業系統來講就建立了一個程序,在這個過程中,伴隨著資源的分配和釋放。可以認為程序是一個程式的一次執行過程。 程序通訊的概念 程序使用者空間是相互獨立的,一般而言是不能相互訪問的。但很多情況下程序間需要互相通

QtQt之程序通訊(Windows訊息)

簡述 通過上一節的瞭解,我們可以看出程序通訊的方式很多,今天分享下如何利用Windows訊息機制來進行不同程序間的通訊。 效果 傳送訊息 自定義型別與接收窗體 包含所需庫,定義傳送的自定義型別、接收訊息的窗體標題。自定義型別可以處理訊息過多情況下,對訊息的區分,如果不需要也可以去掉。

QtQt之程序通訊(共享記憶體)

簡述 上一節中,我們分享下如何利用Windows訊息機制來進行不同程序間的通訊。但是有很多侷限性,比如:不能跨平臺,而且必須兩個程序同時存在才可以,要麼程序A發了訊息誰接收呢? 下面我們來分享另外一種跨平臺的進行間通訊的方式-Shared Memory(共享記憶體)。 簡述 注意事項

QtQt之程序通訊(QProcess)

簡述 前幾節裡,分享了程序通訊的幾種方式:Windows訊息機制、Shared Memory(共享記憶體),本節講解下關於程序通訊的另外一種方式-QProcess。 簡述 命令列讀取 說明 實現 更多參考 命令列引數啟動 說明 程序A-帶參啟動

QtQt之程序通訊(IPC)

簡述 程序間通訊,就是在不同程序之間傳播或交換資訊。那麼不同程序之間存在著什麼雙方都可以訪問的介質呢?程序的使用者空間是互相獨立的,一般而言是不能互相訪問的,唯一的例外是共享記憶體區。但是,系統空間卻是“公共場所”,所以核心顯然可以提供這樣的條件。除此以外,那就是雙方都可以訪問的外設了。在這個意義上,兩

react父子元件之間通訊props

實現父子元件雙向資料流整體的思路是: 1,父元件可以向子元件傳遞props,props中帶有初始化子元件的資料,還有回撥函式 2,子元件的state發生變化時,在子元件的事件處理函式中,手動觸發父函