React組件間通訊

react由於組件化,使得組件間通訊十分的重要。本文就來簡單介紹一些常見的react組件間傳遞的內容。 我將概括爲如下幾種關係來詳述:父組件與子組件之間子組件與父組件之間發佈者與訂閱者模式(context)兄弟組件間,redux也是一種組件管理的方法,可是redux狀態管理的內容比較多,這裏只作簡單介紹,以後再另開一篇詳述。react

父組件向子組件通訊

react的數據流是單向的,最多見的就是經過props由父組件向子組件傳值。redux

示例(關鍵部分有註釋):

咱們作一個簡單的選擇商品,而後改變價格的事例。 segmentfault

父組件: 父組件就是兩個按鈕,用來切換商品的價格,其中引用了子組件。

class Parents extends Component {
   //構造函數
  constructor() {
    super();
    // 設置state
    this.state = {
      price: 0
    };
  }

clickGoods(e) {
    //更新state
    this.setState({
        price: e
    });
}


  // 渲染
  render() {
    let { price } = this.state;
    return (
      <div>
        <button onClick={this.clickGoods1.bind(this)}>goods1</button>
        <button onClick={this.clickGoods2.bind(this)}>goods2</button>
        // 父組件中
        <Child price={price} />
      </div>
    );
  }
}
複製代碼

子組件: 子組件中使用props屬性接收傳遞來的數據。bash

class Child extends Component {
  render() {
  {/*這裏從props中拿到*/}
    return <div> price: {this.props.price} </div>;
  }
}
複製代碼

在線代碼

codesandbox.io/s/718o454r6…markdown

子組件向父組件通訊

接下來咱們反過來,讓子組件向父組件通訊。 子組件向父組件通訊的基本思路是,父組件向子組件傳一個函數,而後經過這個函數的回調,拿到子組件傳過來的值。下面是例子,正好和上面是反的,父組件用來顯示價格,子組件顯示兩個按鈕,子組件把價格傳遞給父組件。app

示例(關鍵部分有註釋):

父組件ide

class Parents extends Component {
  constructor() {
    super();
    this.state = {
      price: 0
    };
  }

  getItemPrice(e) {
    this.setState({
      price: e
    });
  }

  render() {
    return (
      <div>
        <div>price: {this.state.price}</div>
        {/* 向子組件中傳入一個函數  */}
        <Child getPrice={this.getItemPrice.bind(this)} />
      </div>
    );
  }
}
複製代碼

子組件函數

class Child extends Component {
  clickGoods(e) {
    // 在此函數中傳入值
    this.props.getPrice(e);
  }

  render() {
    return (
      <div>
        <button onClick={this.clickGoods.bind(this, 100)}>goods1</button>
        <button onClick={this.clickGoods.bind(this, 1000)}>goods2</button>
      </div>
    );
  }
}
複製代碼

在線代碼

codesandbox.io/s/718o454r6…oop

發佈者與訂閱者模式(context)

React 的props都是由父組件傳遞給子組件的,一旦遇到孫組件,就須要一層層的傳遞下去。而context提供了一種組件之間通信的新的方式(16.3版本以後),能夠共享一些數據,其它的組件都能從context中讀取數據(相似於有個數據源,組件能夠訂閱這個數據源)。組件化

使用方法

React.createContext()方法

咱們可使用createContext來建立一個context,它能夠接收一個變量或者對象作爲參數(當對象爲參數的時候,react使用object.is()去比較,有些影響性能)。這個傳入的值作爲context的默認值

const PriceContext = React.createContext('price')
複製代碼

這樣就建立了一個Context

Provider組件

Provider就是用來建立數據源的。它是給全部的子組件提供數據源的跟組件。它接受一個value做爲props,用來傳遞值,它會改變context的默認值。一個provider能夠包含多個Consumer組件。若是Provider組件嵌套的話,

<PriceContext.Provider value={100}>
</PriceContext.Provider>
複製代碼

Consumer組件

Consumer表示接受數據的組件,它接受一個函數作爲子元素。這個函數會接收context傳遞的值,返回一個react的組件。Consumer組件必須包含在Provider裏面。

<PriceContext.Consumer>
    { /*這裏是一個函數*/ }
    {
        price => <div>price:{price}</div>
    }
</PriceContext.Consumer>
複製代碼

示例

在這部分咱們嘗試一下從父組件直接傳遞到孫組件,不經過子組件(直接從A組件傳值到C組件,不通過B組件)。

// 建立Context
const PriceContext = React.createContext('price')
// A組件中
class ClassA extends Component {
  constructor(){
    super()
    this.state={
      price:0
    }
  }
  // 點擊按鈕事件
  clickGoods(e) {
    this.setState({
      price:e
    })
  }
  render(){
    const { price } = this.state
    return(
      // Provider
      // 把state裏price轉到Provider的value中
    <PriceContext.Provider value={price}>
        <button onClick={this.clickGoods.bind(this, 100)}>goods1</button>
        <button onClick={this.clickGoods.bind(this, 1000)}>goods2</button>
        <ClassB />
    </PriceContext.Provider>  
    )
  }
}
// 組件B
class ClassB extends Component {
  // 組件B中只是引用了ClassC,沒有進行傳值的操做
  render(){
    return(
      <div><span>price:</span><span><ClassC /></span></div>
    )
  }
}
// 組件C
class ClassC extends Component {
  render(){    
    return(
      // Consumer,注意Consumer的下面要包含一個函數
      <PriceContext.Consumer>
        {
          price=><span>{price}</span>
        }
      </PriceContext.Consumer>
    )
  }
}
複製代碼

context的總結與理解

一個react app是由不少react組件組成的,有的組件之間是有嵌套關係的,能夠造成一條「組件鏈」。Context能夠當作組件的「做用域」[3]。一個根組件,它定義了一個context,它的組件鏈上的組件均可以訪問到provider中定義的變量或對象,以下圖所示,這就比較像‘做用域’的概念。context在一些簡單的場景下能夠替代部分redux的功能。

在線代碼

codesandbox.io/s/718o454r6…

兄弟組件間通訊

兄弟間組件通訊,通常的思路就是找一個相同的父組件,這時候既能夠用props傳遞數據,也能夠用context的方式來傳遞數據。 固然也能夠用一些全局的機制去實現通訊,好比redux等。

小結

本文主要介紹了3種通訊的關係父組件與子組件之間子組件與父組件之間發佈者與訂閱者模式(context),簡述了兄弟組件間的通訊。主要是介紹兩種方式,利用props屬性和Context。也介紹了一些context的理解。

Reference:

[1] segmentfault.com/a/119000001…

[2] taobaofed.org/blog/2016/1…

[3] juejin.cn/post/684490…

相關文章
相關標籤/搜索