溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用React怎么實現組件間的通信

發布時間:2021-04-07 17:30:13 來源:億速云 閱讀:220 作者:Leah 欄目:web開發

今天就跟大家聊聊有關使用React怎么實現組件間的通信,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

處理組件之間的通信, 主要取決于組件之間的關系,因此我們劃分為以下三種:

  1. 【父組件】向【子組件】傳值;

  2. 【子組件】向【父組件】傳值;

  3. 【組件A】向無關系【組件B】傳值,一般為兄弟組件;

一、「父組件」向「子組件」傳值

這是最普遍的用法,實現上也非常簡單,主要是利用props來實現

// 父組件
import React from 'react';
import Son from './components/son';
class Father extends React.Component {
  constructor(props) {
    // 這里要加super,否則會報錯
    super(props);
    this.state = {
      checked: true
    }
  }

  render() {
    return (
      <Son text="Toggle me" checked={this.state.checked} />
    )
  }
}
// 子組件
class Son extends React.Component {
  render() {
    // 接收來自父組件的參數
    let checked = this.props.checked,
      text = this.props.text;
    return (
      <label>{text}: <input type="checkbox" checked={checked} /></label>
    )
  }
}

多想一點:

如果組件的嵌套層次太多,那么從外到內的交流成本就會加深,通過 props 傳值的優勢就不明顯,因此,我們還是要盡可能的編寫結構清晰簡單的組件關系, 既也要遵循組件獨立原則,又要適當控制頁面,不可能或極少可能會被單用的代碼片,可不編寫成一個子組件

二、「子組件」向「父組件」傳值

我們知道,react的數據控制分為兩種,為 props 和 state;其中,props 如上剛介紹過,它是父組件向子組件傳值時作為保存參數的數據對象;而 state 是組件存放自身數據的數據對象。這兩者最主要的區別就是,props屬于父組件傳給子組件的只讀數據,在子組件中不能被修改,而state在自身組件中使用時,可以通過setState來修改更新。

子組件向父組件傳值,需要控制自己的state,并發起父組件的事件回調來通知父組件

// 父組件
import Son from './components/son';
class Father extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      checked: false
    }
  }
  onChildChanged() {
    this.setState({
      checked: newState
    })
  }

  render() {
    let isChecked = this.state.checked ? 'yes' : 'no';
    return (
      <div>
        <span>Are you checked: {isChecked }</span>
        <Son text="Toggle me" 
           initialChecked={this.state.checked}
           callbackParent={this.onChildChanged.bind(this)}
         ></Son>
      </div>
    )
  }
}
// 子組件
class Son extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.initialChecked
    }
  }
  onTextChange() {
    let newState = !this.state.check.checked;
    this.setState({
      checked: newState
    });
    // 注意,setState 是一個異步方法,state值不會立即改變,回調時要傳緩存的當前值,   
    // 也可以利用傳遞一個函數(以上傳的是對象),并傳遞prevState參數來實現數據的同步更新
    this.props.callbackParent(newState);
  }
  render() {
    let text= this.props.text;
    let checked = this.state.checked;
    return (
      <label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange.bind(this)}></label>
    )
  }
}

多想一點:

  1. 同樣應當避免深層次的組件嵌套

  2. 這里其實是依賴了props來傳遞事件的引用,并通過回調的方式來實現,在沒有使用工具情況下,可以使用該辦法

拓展一點:

在onChange 事件或者其他React事件中,你能獲取以下信息:

  1. 「this」 指向你的組件

  2. 「一個參數」 一個react合成事件, SyntheticEvent

我們知道,React對所有事件的管理都是自己封裝實現的,html中的 onclick 被封裝成了 onClick, onchange 被封裝成了 onChange。從根本上來說,他們都是被綁定在body上的。

多個子組件回調同一個回調函數情況

父組件中大概率包含多個子組件,為節省和簡潔代碼,遵循 don't repeat yourself 原則,我們會讓一個回調函數實現多個子組件的功能,或多個組件協作完成指定功能

import React from 'react';
import Son from './components/son';
class Father extends React.Componnet {
  constructor(props) {
    super(props);
    this.state = {
      totalChecked: 0
    }
  }
  onChildChangeed() {
    let newTotal = this.state.totalChecked + (new State ? 1 : -1 );
    this.setState({
       totalChecked = this.state.totalChecked;
    });
  }
  render() {
    return (
      <div>
        <div>Checked numbers: {this.state.totalChecked}</div>
        <Son text="Toggle me" initialChecked={this.state.checked} callbackParent={this.onChildChanged} />
        <Son text="Toggle me too" initialChecked={this.state.checked} callbackParent={this.onChildChanged} />
         <Son text="Add me" initialChecked={this.state.checked} callbackParent={this.onChildChanged} />
      </div>
    )
  }
}
// 子組件
class Son extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.initialChecked
    }
  } 

  onTextChange() {
    let newState = !this.state.checked;
    this.setState({
      checked: newState
    })
    // setState異步方法問題,注意傳值
    this.props.callbackParent(newState);
  }

  render() {
    let text = this.props.checked;
    let checked = this.state.checked;
    return {
      <label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange.bind(this)} /></label>
    }
  }
}

多想一點:

在本案例中,我們引用了三個 Son 子組件, 每個 Son 組件都獨立工作互不干擾,該例中,增加了一個 totalChecked 來替代之前的 checked, 當組件觸發onTextChange 后,觸發父組件的回調函數使得父組件的值得以改變。

三、組件A和無關系組件B之間的通信

如果組件之間沒有任何關系,或者組件嵌套的層次比較深,或者,你為了一些組件能夠訂閱,寫入一些信號,不想讓兩個組件之間插入一個組件,而是讓兩個組件出于獨立的關系。對于時間系統,有兩個基本操作:

  1. 訂閱: subscribe

  2. 監聽: listen

并發送 send / 觸發 trigger / 發布 publish / 發送 dispatch 通知那些想要的組件

1. Event Emitter/Target/Dispatcher

特點: 需要一個指定的訂閱源

// to subscribe
otherObiect.addEventListener('clickEvent', function() {
  alert('click!');
})
// to dispatch
this.dispatchEvent('clickEvent');

2. Publish / Subscribe

特點: 觸發的時候,不需要指定一個特定的源,使用全局對象廣播的方式來處理事件

// to subscribe
globalBroadcaster.subcribe('clickEvent', function() {
  alert('cilck!');  
})
// to publish
globalBroadcaster.publish('clickEvent');

這種方案還有一個插件可用, 即 PubSubJs;用法如下:

import Pubsub from 'pubsub-js';
...
// to subscribe
Pubsub.subscribe('EVENT', (msg, param) => {
  console.log(msg, param);
});
// to publish
Pubsub.publish('EVENT', param);

3. Single

特點: 與 Event Emitter/Target/Dispatcher 類似,但是不要使用隨機字符串作為事件觸發的引用。觸發事件的每一個對象都需要一個確切的名字,并且在觸發的時候,也必須要指定確切的事件

// to subscribe
otherObject.clicked.add(function() {
  alert('click');
})
// to dispatch
this.clicked.dispatch();

React 團隊使用的是:js-signals 它基于 Signals 模式,用起來相當不錯。

事件訂閱與取消

使用React事件的時候,必須關注以下兩個方法:

  1. componentDidMount

  2. componentWillUnmount

在 componentDidMount 事件中,等待組件掛載 mounted 完成,再訂閱事件;訂閱的事件需要在組件卸載 componentWillUnmount 的時候取消事件的訂閱。

因為組件的渲染和銷毀是有 React 來控制的,我們不知道怎么引用他們,所以EventEmitter 模式在處理事件的時候用處不大,Pub/Sub 模式就好用些,因為我們不需要知道引用在哪。

ES6策略: yield and js-csp

ES6中有一種傳遞信息的方式,使用生成函數 generators 和 yield 關鍵字,用法參考以下例子

import csp from 'js-csp';

function* list() {
  for(var i = 0; i< arguments.length; i++) {
    yield arguments[i];
  }
  return "done";
}
var o = list(1, 2, 3);
var cur = o.next;
while (!cur.done) {
  cur = o.next();
  console.log(cur);
}

看完上述內容,你們對使用React怎么實現組件間的通信有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女