搜尋
首頁web前端js教程簡單常用技巧之React組件間通訊(整理分享)

本篇文章為大家帶來了React組件間通信簡單易用的常用方式,React知識中一個主要內容便是組件之間的通信,以下列舉幾種常用的組件通信方式,結合實例,通俗易懂,建議收藏,希望對大家有幫助。

簡單常用技巧之React組件間通訊(整理分享)

一、父子元件通訊

原則:父元件透過props(與vue中的props區分開)向子元件通信,子元件透過回呼事件與父元件通訊。

首先,先建立一個父元件Parent.js跟子元件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 (
      <p>
        </p><p>父子组件通信实例</p>
        <button>父传子</button>
        <children></children>
      
    )
  }
}

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 (
      <p>
        </p><p>从父组件传过来:</p>
        <span>{this.state.msg}</span>
      
    )
  }
}

export default Children

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

# 那麼子元件想傳送值給父元件(向上傳值),可以透過呼叫父元件傳過來的回呼函數

在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 (
      <p>
        </p><p>父子组件通信实例</p>
        <span>{this.state.fromChildrn}</span>
        <children></children>
      
    )
  }
}

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 (
      <p>
        </p><p>从父组件传过来:</p>
        <span>{this.state.msg}</span>
        <button>子传父</button>
      
    )
  }
}

export default Children

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

#小結: 以上為直接父子元件通訊的其中一種方式,父傳子,透過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 (
      <p>
        </p><p>context通信实例</p>
        <mycontext.provider>
          <children></children>
        </mycontext.provider>
      
    )
  }
}

export default Parent

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

import React from 'react';
import Grandson from './Grandson';

class Children extends React.Component {
  render(){
    return (
      <p>
        <grandson></grandson>
      </p>
    )
  }
}

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 (
      <p>
        </p><p>通过context传过来:</p>
        <span>{this.context.text}</span>
      
    )
  }
}

export default Grandson

透過this.context.text取得到傳遞的值。

 以上的是一個父-->孫的過程,也就是向下的流程,如果想孫-->父向上傳值,可以透過回呼的方式

对父组件进行传值修改,在传过来的对象中添加一个属性,里面绑定父组件的方法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 (
      <p>
        </p><p>context通信实例</p>
        <span>{this.state.msg}</span>
        <mycontext.provider>
          <children></children>
        </mycontext.provider>
      
    )
  }
}

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 (
      <p>
        </p><p>通过context传过来:</p>
        <span>{this.context.text}</span>
        <p><button>context向上</button></p>
      
    )
  }
}

export default Grandson

默认的页面为:

 点击按钮之后,执行context中的回调,向上传值。

 不管层级有多深,都可以使用context进行向下或向上传值。

注意:在下层组件中取的context中的字段需与value中传递字段保持一致。text与toParent

 

以上就是Context的大致使用,更多细节请往React官方文档:

Context – React=https://react.docschina.org/docs/context.html

三、兄弟(无嵌套)组件通信

当两个组件互不嵌套,处在同个层级或者不同层级上,他们之间要进行通信,有以下几种常用方法

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 (
      <p>
        <grandson></grandson>
        <grandsonother></grandsonother>
      </p>
    )
  }
}

export default Children

组件一,导入event,在componentDidMount阶段添加监听addListener(订阅),在componentWillUnmount移除监听removeListener,事件名称与组件二中emit一致。

import React from 'react';
import event from '../event';

class Grandson extends React.Component {
  constructor(props) {
	super(props);
    this.state = {
      msg:''
    }
  }
  componentDidMount(){
    event.addListener('eventMsg',val => {
      this.setState({
        msg:val
      })
    })
  }
  componentWillUnmount(){
    event.removeListener('eventMsg')
  }
  render(){
    return (
      <p>
        </p><p>组件一</p>
        <p>通过event传过来:</p>
        <span>{this.state.msg}</span>
      
    )
  }
}

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','通过evnet传过来的值')
  }
  render(){
    return (
      <p>
        </p><p>组件二</p>
        <span>{this.state.msg}</span>
        <p><button>event传值</button></p>
      
    )
  }
}

export default Grandson

点击按钮,组件二发布事件,组件一监听(订阅)事件,更新内容。(如果交换发布者订阅者身份,写法一致)

注意:如果两个组件使用event进行通信,确保发布订阅的事件名称一致,如上例中 eventMsg

小结: event的方式比较灵活,不管是父子、跨级、还是同级,甚至毫无关联的组件,都可以使用此方式进行通信。

四、路由传值

React学习笔记 -- 组件通信之路由传参(react-router-dom)_前端菜小白leo的博客-CSDN博客

五、Redux

Redux基本用法(在react中使用,链路打通)_前端菜小白leo的博客-CSDN博客

总结:主要讲了react中常用的组件通信方式,在平时工作中,根据不同的应用场景,选择不同的通信方式,会让通信流程更加简单、清晰。

对比Vue中的组件通信方式,你会发现很多相似之处:

Vue组件间的通信方式(多种场景,通俗易懂,建议收藏)_前端菜小白leo的博客-CSDN博客

推荐学习:《react视频教程

以上是簡單常用技巧之React組件間通訊(整理分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
react中canvas的用法是什么react中canvas的用法是什么Apr 27, 2022 pm 03:12 PM

在react中,canvas用于绘制各种图表、动画等;可以利用“react-konva”插件使用canvas,该插件是一个canvas第三方库,用于使用React操作canvas绘制复杂的画布图形,并提供了元素的事件机制和拖放操作的支持。

react中antd和dva是什么意思react中antd和dva是什么意思Apr 21, 2022 pm 03:25 PM

在react中,antd是基于Ant Design的React UI组件库,主要用于研发企业级中后台产品;dva是一个基于redux和“redux-saga”的数据流方案,内置了“react-router”和fetch,可理解为应用框架。

React是双向数据流吗React是双向数据流吗Apr 21, 2022 am 11:18 AM

React不是双向数据流,而是单向数据流。单向数据流是指数据在某个节点被改动后,只会影响一个方向上的其他节点;React中的表现就是数据主要通过props从父节点传递到子节点,若父级的某个props改变了,React会重渲染所有子节点。

react中为什么使用nodereact中为什么使用nodeApr 21, 2022 am 10:34 AM

因为在react中需要利用到webpack,而webpack依赖nodejs;webpack是一个模块打包机,在执行打包压缩的时候是依赖nodejs的,没有nodejs就不能使用webpack,所以react需要使用nodejs。

react中forceupdate的用法是什么react中forceupdate的用法是什么Apr 19, 2022 pm 12:03 PM

在react中,forceupdate()用于强制使组件跳过shouldComponentUpdate(),直接调用render(),可以触发组件的正常生命周期方法,语法为“component.forceUpdate(callback)”。

react是组件化开发吗react是组件化开发吗Apr 22, 2022 am 10:44 AM

react是组件化开发;组件化是React的核心思想,可以开发出一个个独立可复用的小组件来构造应用,任何的应用都会被抽象成一颗组件树,组件化开发也就是将一个页面拆分成一个个小的功能模块,每个功能完成自己这部分独立功能。

react和reactdom有什么区别react和reactdom有什么区别Apr 27, 2022 am 10:26 AM

react和reactdom的区别是:ReactDom只做和浏览器或DOM相关的操作,例如“ReactDOM.findDOMNode()”操作;而react负责除浏览器和DOM以外的相关操作,ReactDom是React的一部分。

react与vue的虚拟dom有什么区别react与vue的虚拟dom有什么区别Apr 22, 2022 am 11:11 AM

react与vue的虚拟dom没有区别;react和vue的虚拟dom都是用js对象来模拟真实DOM,用虚拟DOM的diff来最小化更新真实DOM,可以减小不必要的性能损耗,按颗粒度分为不同的类型比较同层级dom节点,进行增、删、移的操作。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
1 個月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)