1. 程式人生 > 程式設計 >React元件間通訊的三種方法(簡單易用)

React元件間通訊的三種方法(簡單易用)

目錄
  • 一、父子元件通訊
  • 二、跨級元件通訊
    • 1、逐層傳值
    • 2、跨級傳值
  • 三、兄弟(無巢狀)元件通訊
    • 四、路由傳值
      • 五、Redux

        React知識中一個主要內容便是元件之間的通訊,以下列舉幾種常用的元件通訊方式,結合例項,通俗易懂,建議收藏。

        一、父子元件通訊

        原理:父元件通過props(與中的props區分開)向子元件通訊,子元件通過回撥事件與父元件通訊。

        首先,先建立一個父元件Parent.跟子元件Children.js,二者的關係為直接父子關係。

        Parent.js父元件如下,給父元件一個預設狀態state,引入子元件,通過在子元件加上toChildren={this.state.msg},該處即為向子元件傳props。

        import React from 'react';
        import { Button } from 'element-react';
        import Children from './Children';
         
        class Parent extends React.Component {
          constructor(props) {
        	super(props);
        	this.state = {
        		msg:'父元件傳遞給子元件'
        	};
            this.changeMsg = this.changeMsg.bind(this)
          }
          changeMsg(){
            this.setState({
              msg:'父元件傳遞給子元件(改變之後的內容)'
            })
          }
          render(){
            return (
              <div style={{backgroundColor:'#f7ba2a',padding:'20px',width:'500px',margin:'auto',textAlign:'center'}}>
                <p>父子元件通訊例項</p>
                <Button onClick={this.changeMsg}>父傳子</Button>
                <Children toChildren={this.state.msg}></Children>
              </div>
            )
          }
        }
         
        export default Parent

        Children.js子元件如下,初始狀態通過props拿到父元件傳過來的值。

        import React from 'react';
         
        class Children extends React.Component {
          constructor(props) {
        	super(props);
        	this.state = {
        		msg:this.props.toChildren   //通過props拿到父元件傳過來的值
        	};
          }
          render(){
            return (
              <div style={{backgroundColor:'#13ce66',padding:'10px',width:'200px',marginTop:'20px'}}>
                <p>從父元件傳過來:</p>
                <span style={{color:'blue'}}>{this.state.msg}&http://www.cppcns.com
        lt;/span> </div> ) } } export default Children

        React元件間通訊的三種方法(簡單易用)

        注意:子元件取值時應與父元件放在子元件的欄位props一致,即本例中的 toChildren,如下

        React元件間通訊的三種方法(簡單易用)

        React元件間通訊的三種方法(簡單易用)

        那麼子元件想向父元件傳值(向上傳值),可以通過呼叫父元件傳過來的回撥函式

        在Parent.js中向Children.js中加入回撥函式callback,繫結changeMsg方法

        import React from 'react';
        import Children from './Children';
         
        class Parent extends React.Component {
          constructor(props) {
        	super(props);
        	this.state = {
        	    msg:'父元件傳遞給子元件',fromChildrn:''
        	};
            this.changeMsg = this.changeMsg.bind(this)
          }
          changeMsg(val){
            this.setState({
              fromChildrn: val
            })
          }
          render(){
            return (
              <div style={{backgroundColor:'#f7ba2a',textAlign:'center'}}>
                <p>父子元件通訊例項</p>
                <span style={{color:'red'}}>{this.state.fromChildrn}</span>
                <Children toChildren={this.state.msg} callback={this.changeMsg}></Children>
              </div>
            )
          }
        }
         
        export default Parent

        在子元件中,用this.props.callback()執行父元件的回撥函式,從而執行繫結方法changeMsg,顯示子元件傳過來的值

        import React from 'react';
        import { Button } from 'element-react';
         
        class Children extends React.Component {
          constructor(props) {
        	super(props);
        	this.state = {
        		msg:this.props.toChildren
        	};
            this.toParent = this.toParent.bind(this)
          }
          toParent(){
            this.props.callback('子元件傳過來的值')   //子元件通過此觸發父元件的回撥方法
          }
          render(){
            return (
              <div style={{backgroundColor:'#13ce66',marginTop:'20px'}}>
                <p>從父元件傳過來:</p>
                <span style={{color:'blue'}}>{this.state.msg}</span>
                <Button onClick={this.toParent}>子傳父</Button>
              </div>
            )
          }
        }
         
        export default Children

        注意:props中的回撥函式名稱需一致,即本例中的callback,如下

        React元件間通訊的三種方法(簡單易用)

        React元件間通訊的三種方法(簡單易用)

        小結: 以上為直接父子元件通訊的其中一種方式,父傳子,通過props;子傳父,執行回撥。

        二、跨級元件通訊

        假設一個父元件中存在一個子元件,這個子元件中又存在一個子元件,暫且稱為“孫元件”,當父元件需要與“孫元件”通訊時,常用的方式有兩種,逐層傳值與跨層傳值。

        1、逐層傳值

        這種方式就是上面的直接父子通訊的基礎上在加上一個中間層。如父、“孫”元件通訊,可以先父子通訊,然後再子“孫”通訊,傳遞的層級變成父-->子-->“孫”,同理,通過props往下傳,通過回撥往上傳。不展開,有興趣的自己動手實現一下。

        2、跨級傳值

        顧名思義,父跟“孫”通訊,不需要經過子(中間層)元件。這裡引出了Context

        React官方文件對Context做出瞭解釋:

        在一個典型的 React 應用中,資料是通過 props 屬性自上而下(由父及子)進行傳遞的,但這種做法對於某些型別的屬性而言是極其繁瑣的(例如:地區偏好,UI 主題),這些屬性是應用程式中許多元件都需要的。Context 提供了一種在元件之間共享此類值的方式,而不必顯式地通過元件樹的逐層傳遞 props。

        一句話概括就是:跨級傳值,狀態共享

        看下簡單的例項,直接講用法。

        首先,我先建立一個context.js檔案(與父子孫同個目錄),預設值為一個物件。

        import React from "react";
        const MyContext = React.createContext({text:'luck'});
        export default MyContext

        然後,對父元件進行改寫,引入context,使用一個 Provider 來將當前的 value 傳遞給以下的元件樹,value為傳遞的值。

        import React from 'react';
        import Children from './Children';
        import MyContext from './context';
         
        class Parent extends React.Component {
          constructor(props) {
        	super(props);
          }
          // 使用一個 Provider 來將當前的 value 傳遞給以下的元件樹。
          // 無論多深,任何元件都能讀取這個值。
          render(){
            return (
              <div style={{backgroundColor:'#f7ba2a',textAlign:'center'}}>
                <p>context通訊例項</p>
                <MyContext.Provider value={{text:'good luck'}}>
                  <Children></Children>
                </MyContext.Provider>
              </div>
            )
          }
        }
         
        export default Parent

        子元件為中間層,不做處理,用於包裹“孫”元件。

        import React from 'react';
        import Grandson from './Grandson';
         
        class Children extends React.Component {
          render(){
            return (
              <div>
                <Grandson></Grandson>
              </div>
            )
          }
        }
         
        export default Children

        新增一個“孫”元件,同樣需引入context,在元件內部新增static contextType = MyContext,此時將能通過this.context直接獲取到上層距離最近的Provider傳遞的值,此時this.context = {text:good luck},即父元件傳遞value。

        import React from 'react';
        import MyContext from './context';
         
        class Grandson extends React.Component {
          static contextType = MyContext
          render(){
            return (
              <div style={{backgroundColor:'#13ce6GORHA6',marginTop:'20px'}}>
                <p>通過context傳過來:</p>
                <span style={{color:'blue'}}>{this.context.text}</span>
              </div>
            )
          }
        }
         
        export default Grandson

        通過this.context.text獲取到傳遞的值。

        React元件間通訊的三種方法(簡單易用)

        以上的是一個父-->孫的過程,即向下的流程,如果想孫-->父向上傳值,可以通過回撥的方式

        對父元件進行傳值修改,在傳過來的物件中新增一個屬性,裡面繫結父元件的方法value={{text:'good luck',toParent:this.fromGranson}}

        import React from 'react';
        import Children from './Children';
        import MyContext from './context';
         
        class Parent extends React.Component {
          constructor(props) {
        	super(props);
            this.state = {
              msg:''
            };
            this.fromGranson = this.fromGranson.bind(this)
          }
          fromGranson(val){
            this.setState({
              msg:val
            })
          }
          // 使用一個 Provider 來將當前的 theme 傳遞給以下的元件樹。
          // 無論多深,任何元件都能讀取這個值。
          render(){
            return (
              <div style={{backgroundColor:'#f7ba2a',textAlign:'center'}}>
         www.cppcns.com       <p>context通訊例項</p>
                <span style={{color:'red'}}>{this.state.msg}</span>
                <MyContext.Provider value={{text:'good luck',toParent:this.fromGranson}}>
                  <Children></Children>
                </MyContext.Provider>
              </div>
            )
          }
        }
         
        export default Parent

        然後在孫元件中新增一個按鈕,繫結方法,執行函式回撥

        toParent(){
            this.context.toParent('孫元件向父元件傳資料')
         }
        import React from 'react';
        import MyContext from './context';
        import { Button } from 'element-react'
         
        class Grandson extends React.Component {
          static contextType = MyContext
          constructor(props) {
        		super(props);
            this.toParent = this.toParent.bind(this)
        	}
          toParent(){
            this.context.toParent('孫元件向父元件傳資料')
          }
          render(){
            return (
              <div style={{backgroundColor:'#13ce66',marginTop:'20px'}}>
                <p>通過context傳過來:</p>
                <span style={{color:'blue'}}>{this.context.text}</span>
                <div><Button onClick={this.toParent}>context向上</Button></div>
              </div>
            )
          }
        }
         
        export default Grandson

        預設的頁面為:

        React元件間通訊的三種方法(簡單易用)

        點選按鈕之後,執行context中的回撥,向上傳值。

        React元件間通訊的三種方法(簡單易用)

        不管層級有多深,都可以使用context進行向下或向上傳值。

        注意:在下層元件中取的context中的欄位需與value中傳遞欄位保持一致。text與toParent

        React元件間通訊的三種方法(簡單易用)

        React元件間通訊的三種方法(簡單易用)

        以上就是Context的大致使用,更多細節請往React官方文件:

        Context – React

        三、兄弟(無巢狀)元件通訊

        當兩個元件互不巢狀,處在同個層級或者不同層級上,他們之間要進行通訊,有以下幾種常用方法

        1、某個元件先將值傳到同一個父元件,然後在通過父元件傳給另外一個元件,用到父子元件傳值

        2、使用快取sessionStorage、localStorage等

        3、如果兩個元件之間存在跳轉,可以使用路由跳轉傳值,附上詳細用法

        React學習筆記 -- 元件通訊之路由傳參(react-router-dom)_前端菜小白leo的部落格-CSDN部落格

        4、event(釋出--訂閱)

        首先,安裝event

        npm install event -save

        新建一個event.js

        import { EventEmitter } from 'events';
        export default new EventEmitter();

        然後另兩個元件處於同層級(不同個父元件或者不同層級都可以)

        import React from 'react';
        import Grandson from './Grandson';
        import GrandsonOther from './GrandsonOther';
         
        class Children extends React.Component {
          render(){
            return (
              <div>
                <Grandson></Grandson>
                <GrandsonOther></GrandsonOther>
              </div>
            )
          }
        }
         
        export default Children

        元件一,匯入event,在componentDidMount階段新增監聽addListener(訂閱),在componentWillUnmount移除監聽removeListener,事件名稱與元件二中emit一致。

        import React from 'react';
        import event from '../event';
        import { Button } from 'element-react'
         
        class Grandson extends React.Component {
          constructor(props) {
        	super(props);
            this.state = {
              msg:''
            }
            this.toOther = this.toOther.bind(this)
          }
          toOther(){
            event.emit('eventMsg','通過evnet傳過來的值')
          }
          render(){
            return (
              <div style={{backgroundColor:'#13ce66',marginTop:'20px'}}>
                <p>元件二</p>
                <span style={{color:'blue'}}>{this.state.msg}</span>
                <div><Button onClick={this.toOther}>event傳值</Button></div>
              </div>
            )
          }
        }
         
        export default Grandson

        元件二,匯入event,按鈕繫結方法,使用event.emit觸發(釋出)事件。

        import React from 'react';
        import event from '../event';
        import { Button } from 'element-react'
         
        class Grandson extends React.Component {
          constructor(props) {
        	super(props);
            this.state = {
              msg:''
            }
            this.toOther = this.toOther.bind(this)
          }
          toOther(){
            event.emit('eventMsg',marginTop:'20px'}}>
                <p>元件二</p>
                <span style={{color:'blue'}}>{this.state.msg}</span>
                <div><Button onClick={this.toOther}>event傳值</Button></div>
              </div>
            )
          }
        }
         
        export default Grandson

        點選按鈕,元件二釋出事件,元件一監聽(訂閱)事件,更新內容。(如果交換髮布者訂閱者身份,寫法一致)

        React元件間通訊的三種方法(簡單易用)

        React元件間通訊的三種方法(簡單易用)

        注意:如果兩個元件使用event進行通訊,確保釋出訂閱的事件名稱一致,如上例中eventMsg

        小結: event的方式比較靈活,不管是父子、跨級、還是同級,甚至毫無關聯的元件,都可以使用此方式進行通訊。

        四、路由傳值

        React學習筆記 -- 元件通訊之路由傳參(react-router-dom)

        五、Redux

        待發布。

        總結:主要講了react中常用的元件通訊方式,在平時工作中,根據不同的應用場景,選擇不同的通訊方式,會讓通訊流程更加簡單、清晰。

        對比Vue中的元件通訊方式,你會發現很多相似之處:

        Vue元件間的通訊方式(多種場景,通俗易懂,建議收藏)

        到此這篇關於React元件間通訊的三種方法(簡單易用)的文章就介紹到這了,更多相關React元件間通訊內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!