首頁  >  文章  >  web前端  >  在react中有關元件通訊有哪些方法?

在react中有關元件通訊有哪些方法?

亚连
亚连原創
2018-06-21 17:20:422199瀏覽

這篇文章主要給大家介紹了關於react中組件通信的幾種方式,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

前言

剛入門React可能會因為React的單向資料流的特性而遇到元件間溝通的麻煩,下面這篇文章就來給大家詳細介紹下,在開始之前先來看一張圖:

#react元件通訊

  • 需要元件之進行通訊的幾種情況

  • 父元件向子元件通訊

  • 子元件向父元件通訊

  • #跨層級元件通訊

  • 沒有巢狀關係元件之間的通訊

1. 父元件向子元件通訊

React資料流動是單向的,父元件向子元件通訊也是最常見的;父元件透過props向子元件傳遞需要的訊息
Child.jsx

import React from 'react';
import PropTypes from 'prop-types';
export default function Child({ name }) {
 return <h1>Hello, {name}</h1>;
}
Child.propTypes = {
 name: PropTypes.string.isRequired,
};

Parent.jsx

import React, { Component } from &#39;react&#39;;
import Child from &#39;./Child&#39;;
class Parent extends Component {
 render() {
  return (
   <p>
    <Child name="Sara" />
   </p>
  );
 }
}
export default Parent;

2. 子元件向父元件通訊

  • 利用回呼函數

  • 利用自訂事件機制

實作在子元件中點擊隱藏元件按鈕可以將自身隱藏的功能

List3.jsx

import React, { Component } from &#39;react&#39;;
import PropTypes from &#39;prop-types&#39;;
class List3 extends Component {
 static propTypes = {
  hideConponent: PropTypes.func.isRequired,
 }
 render() {
  return (
   <p>
    哈哈,我是List3
    <button onClick={this.props.hideConponent}>隐藏List3组件</button>
   </p>
  );
 }
}
export default List3;

App,jsx

import React, { Component } from &#39;react&#39;;
import List3 from &#39;./components/List3&#39;;
export default class App extends Component {
 constructor(...args) {
  super(...args);
  this.state = {
   isShowList3: false,
  };
 }
 showConponent = () => {
  this.setState({
   isShowList3: true,
  });
 }
 hideConponent = () => {
  this.setState({
   isShowList3: false,
  });
 }
 render() {
  return (
   <p>
    <button onClick={this.showConponent}>显示Lists组件</button>
    {
     this.state.isShowList3 ?
      <List3 hideConponent={this.hideConponent} />
     :
     null
    }
   </p>
  );
 }
}
觀察實作方法,可以發現它與傳統回呼函數的實作方法一樣.而且setState一般與回呼函數均會成對出現,因為回呼函數即是轉換內部狀態是的函數傳統;

3. 跨級元件通訊

層層元件傳遞props

#例如A元件和B元件之間要進行通訊,先找到A和B公共的父元件,A先向C元件通訊,C元件透過props和B元件通訊,此時C元件起的就是中間件的作用

##使用context

context是一個全域變數,像是一個大容器,在任何地方都可以存取到,我們可以把要通訊的資訊放在context上,然後在其他元件中可以隨意取到;

但是React官方不建議使用大量context,儘管他可以減少逐層傳遞,但是當組件結構複雜的時候,我們並不知道context是從哪裡傳過來的;而且context是一個全局變量,全局變量正是導致應用走向混亂的罪魁禍首.使用context

下面範例中的元件關係: ListItem是List的子元件,List是app的子元件

# ListItem.jsx

import React, { Component } from &#39;react&#39;;
import PropTypes from &#39;prop-types&#39;;
class ListItem extends Component {
 // 子组件声明自己要使用context
 static contextTypes = {
  color: PropTypes.string,
 }
 static propTypes = {
  value: PropTypes.string,
 }
 render() {
  const { value } = this.props;
  return (
   <li style={{ background: this.context.color }}>
    <span>{value}</span>
   </li>
  );
 }
}
export default ListItem;

List.jsx

import ListItem from &#39;./ListItem&#39;;
class List extends Component {
 // 父组件声明自己支持context
 static childContextTypes = {
  color: PropTypes.string,
 }
 static propTypes = {
  list: PropTypes.array,
 }
 // 提供一个函数,用来返回相应的context对象
 getChildContext() {
  return {
   color: &#39;red&#39;,
  };
 }
 render() {
  const { list } = this.props;
  return (
   <p>
    <ul>
     {
      list.map((entry, index) =>
       <ListItem key={`list-${index}`} value={entry.text} />,
      )
     }
    </ul>
   </p>
  );
 }
}
export default List;

app.jsx

import React, { Component } from &#39;react&#39;;
import List from &#39;./components/List&#39;;
const list = [
 {
  text: &#39;题目一&#39;,
 },
 {
  text: &#39;题目二&#39;,
 },
];
export default class App extends Component {
 render() {
  return (
   <p>
    <List
     list={list}
    />
   </p>
  );
 }
}
##4. 沒有巢狀關係的元件通訊

使用自訂事件機制

在componentDidMount事件中,如果元件掛載完成,再訂閱事件;在元件卸載的時候,在componentWillUnmount事件中取消事件的訂閱;

以常用的發布/訂閱模式舉例,借用Node.js Events模組的瀏覽器版實作

使用自訂事件的方式

下面範例中的元件關係: List1和List2沒有任何巢狀關係,App是他們的父元件;

實作這樣一個功能: 點擊List2中的一個按鈕,改變List1中的信息顯示

    首先需要專案中安裝events 套件:
  • npm install events --save

    在src下新建一個util目錄裡面建一個events.js

    import { EventEmitter } from &#39;events&#39;;
    export default new EventEmitter();
  • list1.jsx
  • import React, { Component } from &#39;react&#39;;
    import emitter from &#39;../util/events&#39;;
    class List extends Component {
     constructor(props) {
      super(props);
      this.state = {
       message: &#39;List1&#39;,
      };
     }
     componentDidMount() {
      // 组件装载完成以后声明一个自定义事件
      this.eventEmitter = emitter.addListener(&#39;changeMessage&#39;, (message) => {
       this.setState({
        message,
       });
      });
     }
     componentWillUnmount() {
      emitter.removeListener(this.eventEmitter);
     }
     render() {
      return (
       <p>
        {this.state.message}
       </p>
      );
     }
    }
    export default List;

    List2.jsx

    import React, { Component } from &#39;react&#39;;
    import emitter from &#39;../util/events&#39;;
    class List2 extends Component {
     handleClick = (message) => {
      emitter.emit(&#39;changeMessage&#39;, message);
     };
     render() {
      return (
       <p>
        <button onClick={this.handleClick.bind(this, &#39;List2&#39;)}>点击我改变List1组件中显示信息</button>
       </p>
      );
     }
    }
  • APP.jsx
  • import React, { Component } from &#39;react&#39;;
    import List1 from &#39;./components/List1&#39;;
    import List2 from &#39;./components/List2&#39;;
    export default class App extends Component {
     render() {
      return (
       <p>
        <List1 />
        <List2 />
       </p>
      );
     }
    }

    自訂事件是典型的發布訂閱模式,透過向事件物件上新增監聽器和觸發事件來實現元件之間的通信

  • 總結
  • 父元件向子元件通訊: props

子元件向父元件通訊: 回呼函數/自定義事件

跨級元件通訊: 層層元件傳遞props/context

沒有巢狀關係元件之間的通訊: 自訂事件

在進行元件通訊的時候,主要看業務的具體需求,選擇最合適的;

當業務邏輯複雜到一定程度,就可以考慮引入Mobx,Redux等狀態管理工具上面是我整理給大家的,希望未來會對大家有幫助。

相關文章:

詳細解讀javascript中map資料結構############使用Javascript如何實作自訂事件機制##### #######使用vue如何實作登入註冊及token驗證############使用vue如何實作token驗證######

以上是在react中有關元件通訊有哪些方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn