react中的父子組件通信和跨級組件通信

父子組件通信

顧名思義就是父組件和子組件之間進行通信交流。下面先看樣例代碼:

// 父子組件通信
import React from "react";

// 下面爲父子組件通信實例代碼
// 父組件
class ParentSon extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      msg: "father",
      name: "partent",
      age: 60
    };
  }

  callback = (msg, name, age) => {
    this.setState({ msg });
    this.setState({ name });
    this.setState({ age });
  };

  render() {
    return (
      <div style={{padding: 30+'px'}}>
        <h1>{this.state.msg}</h1>
        <Child
          callback={this.callback}
          age={this.state.age}
          name={this.state.name}
        ></Child>
      </div>
    );
  }
}

// 子組件
class Child extends React.Component{
  constructor(props){
    super(props);
    this.state={
      msg: 'I am son',
      name: 'son',
      age: 8
    };
    // 下面一行代碼是爲了解決非箭頭函數使用時this的指向問題不能指向當前子組件自身
    // this.change=this.change.bind(this);
  }
  // change(){
  //   // console.log(this);
  //   this.props.callback(this.state.msg,this.state.name,this.state.age);
  // }
  change=()=>{
    this.props.callback(this.state.msg,this.state.name,this.state.age);
  }

  render(){
    return (
      <div>
        <div>{this.props.name}</div>
        <div>{this.props.age}</div>
        <button onClick={this.change}>點擊</button>
      </div>
    )
  }
}

export default ParentSon;

如上面代碼所示,分別創建了父組件 ParentSon 和子組件 Child ,父組件裏面定義了自己的state內容,並定義了一個 callback 方法,此方法用來改變父組件自身的state內容值的,然後render函數裏面除了渲染自身state裏的msg值之外,將自身的callback方法以及自身state裏的name,age分別作爲參數傳給了子組件 Child。

下面再繼續看子組件內部,除了有自己的state之外,還有一個change方法,然後render函數裏渲染了來自props裏的值以及一個點擊事件按鈕,而這個按鈕點擊事件就會觸發調用自身那個change事件,在進入change方法內部會看到,實際上,執行的就是props接收的callback方法,也就是從父組件傳過來的那個callback,而這裏的參數又是子組件自身state的內容值,到此,我們可以順一下整個思路了。

思路: 一開始渲染出的全是父組件的值(因爲子組件顯示的就是來自父組件的值)-----> 點擊按鈕 -----> 觸發子組件change事件(實際接收的父組件callback方法)-----> 父組件callback被調用,父組件的state裏的值都發生改變,此時已變成和子組件state裏一樣的值了 -----> state改變後的值,又通過props傳給了子組件Child -----> 再一次渲染出來傳過來的值,即和子組件一模一樣的值,此時整個過程全部結束。

跨級組件通信

顧名思義就是互不相干且之間隔了好幾級的一種通信交流方式。下面先看樣例代碼:

// 跨級組件通信
import React from "react";

const ThemeContext = React.createContext("light");

class ContextMess extends React.Component {
  static contextType = ThemeContext;
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <div style={{padding: 30+'px'}}>
          <h3>{this.context}</h3>
          <Toolbar></Toolbar>
        </div>
      </ThemeContext.Provider>
    );
  }
}

class Toolbar extends React.Component {
  render() {
    return (
      <div>
        <ThemedButton></ThemedButton>
      </div>
    );
  }
}

class ThemedButton extends React.Component {
  static contextType = ThemeContext;
  render() {
    return (
      <div>
        <h1>{this.context}</h1>
        <ThemeContext.Consumer>
          {value => (<h6>{value}</h6>)}
        </ThemeContext.Consumer>
      </div>
    );
  }
}

export default ContextMess;

從上面代碼可以看出,有三個組件,ContextMess ,Toolbar ,ThemedButton ,ContextMess 爲最外層組件,依次是Toolbar 組件,再是ThemedButton 組件,逐層嵌套。
代碼中主要使用了react中的Context技術點,使用了Context中的以下幾個API:React.createContext,Context.Provider,Class.contextType,Context.Consumer。

React.createContext: 創建一個 Context 對象。當 React 渲染一個訂閱了這個 Context 對象的組件,這個組件會從組件樹中離自身最近的那個匹配的 Provider 中讀取到當前的 context 值。

Context.Provider: 每個 Context 對象都會返回一個 Provider React 組件,它允許消費組件訂閱 context 的變化;Provider 接收一個 value 屬性,傳遞給消費組件;當 Provider 的 value 值發生變化時,它內部的所有消費組件都會重新渲染。

Class.contextType: (代碼中通過 static 來定義靜態屬性contextType,即組件(class)自己的屬性,等同於class.contextType)掛載在 class 上的 contextType 屬性會被重賦值爲一個由 React.createContext() 創建的 Context 對象。這能讓你使用 this.context 來消費最近 Context 上的那個值。你可以在任何生命週期中訪問到它,包括 render 函數中。

Context.Consumer: 這裏,React 組件也可以訂閱到 context 變更。這能讓你在函數式組件中完成訂閱 context;這需要函數作爲子元素(function as a child)這種做法。這個函數接收當前的 context 值,返回一個 React 節點。傳遞給函數的 value 值等同於往上組件樹離這個 context 最近的 Provider 提供的 value 值。如果沒有對應的 Provider,value 參數等同於傳遞給 createContext() 的 defaultValue。

思路: 簡單來說,那個‘light’一開始創建的就相當於要在其他組件使用的數據,在 ContextMess 組件中通過使用 contextType 獲取 createContext 創建的對象,然後通過this.context來獲取值,即“light”;除此之外,使用 Context.Provider API 通過value參數將當前值改爲“dark”,然後不使用 props 傳值方式,在二級組件中可以看到,並沒有使用props接收值,最後在下一級組件通過 Class.contextType 和 this.context 方式讀取值,除此之外還使用 Context.Consumer API 來獲取最近的那個匹配的context值,即改變後的值“dark”。

具體Context相關知識及API使用請點擊:React中Context的學習使用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章