React 组件间通信介绍
React 组件间通信方式简介
React 组件间通信主要分为以下四种情况:
- 父组件向子组件通信
- 子组件向父组件通信
- 跨级组件之间通信
- 非嵌套组件间通信
下面对这四种情况分别进行介绍:
父组件向子组件通信
父组件通过 props 和子组件进行通信,子组件得到 props 后进行相应的操作
父组件 App.js:
import React, { Component } from 'react';import './App.css';import Child1 from './Child1';class App extends Component {render() {return (<div className="App"><Child1 content="父组件传递的内容" /></div>);}}export default App;
子组件 Child1.jsx
import React, { Component } from 'react';class Child1 extends Component {render () {return (<div>子组件一:{ this.props.content }</div>)}}export default Child1;
子组件向父组件通信
和父组件向子组件通信类似,父组件通过传递 props 给子组件,只不过 props 的内容是一个函数,子组件通过调用父组件传递过来的回调函数,将子组件内容传递给父组件。
父组件 App.js
import React, { Component } from 'react';import logo from './logo.svg';import './App.css';import Child1 from './Child1';import Child2 from './Child2';class App extends Component {constructor(){super();this.state = {msg:'',}}childMsg(msg){this.setState({msg: msg,})}render() {return (<div className="App">子组件二传过来的内容:{this.state.msg}<Child2 childMsg={this.childMsg.bind(this)}/></div>);}}export default App;
子组件 Child2.jsx:
import React, { Component } from 'react';class Child2 extends Component {msgHandle(){this.props.childMsg(this.refs.input.value);}render () {return (<div>子组件二:<input type="text" placeholder='请输入内容' ref='input' /><button onClick={this.msgHandle.bind(this)}>点击向父组件传参</button></div>)}}export default Child2;
跨级组件通信
跨级组件是指父组件向子组件的子组件进行通信,或者向更深层次的子组件通信,主要有两种方式:
- 通过 props 层层传递
- 使用 context 对象
对于层级不深的组件(三层以内),可以使用 props 进行层层传递,如果说层级更深的话,
每一层组件都要去传递 props,并且这些 props 可能不是自身需要的,这就增加了复杂度,这种场景就可以使用 context 进行通信。context 是一个全局变量,相当于一个大容器,我们把要传递的信息放到这个容器里面,不管嵌套层级多深,子组件都可以获取到信息。使用 context 需要满足以下三个条件:
1、父组件需要声明自己支持 context,并提供 context 对象中属性的 PropTypes
2、子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes。
3、父组件需要提供一个 getChildContext 函数,用来返回一个初始的 context 对象
props 层层传递:
父组件App.js:
import React, { Component } from 'react';import logo from './logo.svg';import './App.css';import Child1 from './Child1';class App extends Component {constructor(){super();}render() {return (<div className="App"><Child1 content="父组件传递给孙子组件的内容" /></div>);}}export default App;
Child1.jsx:
import React, { Component } from 'react';import Child1_1 from './Child1_1';class Child1 extends Component {render () {return (<div><Child1_1 content={this.props.content}/></div>)}}export default Child1;
Child1_1.jsx:
import React, { Component } from 'react';class Child1_1 extends Component {render () {return (<div>子组件一的子组件:{ this.props.content }</div>)}}export default Child1_1;
context 对象传递
父组件App.js:
import React, { Component } from 'react';import logo from './logo.svg';import './App.css';import PropTypes from "prop-types";import Child1 from './Child1';class App extends Component {// 声明支持 contextstatic childContextTypes = {msgs: PropTypes.string,callBack: PropTypes.func,}// 父组件提供一个函数,返回初始的 context 对象getChildContext(){return {msgs:'父组件传递的初始内容',callBack:this.callBack}}callBack(msgs){console.log(msgs);}render() {return (<div className="App"><Child1 /></div>);}}export default App;
子组件 Child1.jsx:
import React, { Component } from 'react';import Child12 from './Child1_2';class Child1 extends Component {render () {return (<div><Child12 /></div>)}}export default Child1;
子组件的子组件 Child1_2:
import React, { Component } from 'react';import PropTypes from 'prop-types';class Child1_2 extends Component {// 子组件声明需要调动 contextstatic contextTypes = {msgs:PropTypes.string,callBack:PropTypes.func}callBack(){this.context.callBack('孙子组件的信息');}render () {return (<div>子组件一的子组件:{ this.context.msgs }<button onClick={this.callBack.bind(this)}>点击给爷爷组件传递信息</button></div>)}}export default Child1_2;
非嵌套组件间通信
表示没有任何包含关系的组件,主要包括兄弟组件和不在同一个父级中的非兄弟组件。
- 使用共同父组件的 context 对象通信
- 使用自定义事件的方式
对于使用共同父组件 context 的方式会增加子组件和父组件之间的耦合度,对于层级较深的组件找到共同父组件也比较麻烦,但是这种方式可实施。
为了避免父子组件之间的耦合度,我们采用自定义事件的方式:
需要安装 events 包,使用该模块的自定义事件机制npm i events --save
在根目录下新建 events.js 文件:
import { EventEmitter } from 'events';export default new EventEmitter();
父组件 App.js:
import React, { Component } from 'react';import logo from './logo.svg';import './App.css';import Child1 from './Child1';import Child2 from './Child2';class App extends Component {render() {return (<div className="App"><Child1 /><Child2 /></div>);}}export default App;
子组件 Child1.jsx:
import React, { Component } from 'react';import emitter from './events';class Child1 extends Component {constructor(props){super(props);this.state = {msg:''}}// 组件挂载完后,声明一个自定义事件componentDidMount(){this.eventEmitter = emitter.addListener('selfEventName',msg => {this.setState({msg: msg})})}// 组件销毁前清除事件监听componentWillUnmount(){emitter.removeListener(this.eventEmitter)}render () {return (<div>子组件二传递过来的内容:{ this.state.msg }</div>)}}export default Child1;
子组件 Child2.jsx:
import React, { Component } from 'react';import emitter from './events';class Child2 extends Component {msgHandle(){emitter.emit('selfEventName','自定义事件传参');}render () {return (<div>子组件二:<button onClick={this.msgHandle.bind(this)}>点击向父组件传参</button></div>)}}export default Child2;
React 组件间通信介绍的更多相关文章
- vue 和 react 组件间通信方法对比
vue 和 react 组件间通信方法对比: 通信路径 vue的方法 react的方法 父组件 => 子组件 props(推荐).slot(推荐).this.$refs.this.$childr ...
- React组件间通信-sub/pub机制
React生命周期第二个demo演示了兄弟组件的通信,需要通过父组件,比较麻烦:下面介绍sub/pub机制来事项组件间通信. 1.导包 npm i pubsub-js 2.UserSearch.jsx ...
- React 组件间通信 总结
组件间通信 5.1.1. 方式一: 通过props传递 1) 共同的数据放在父组件上, 特有的数据放在自己组件内部(state) 2) 通过props可以传递一般数据和 ...
- React组件间通信
众所周知,ReactJS组件与组件之间的通信是一个难点.在React实际开发中,父子组件之间的传值是比较常见的,刚入门的小伙伴很容易被组件之间的通信绕懵. 今天花了点时间总结了一下React父子组件之 ...
- react 组件间通信,父子间通信
一.父组件传值给子组件 父组件向下传值是使用了props属性,在父组件定义的子组件上定义传给子组件的名字和值,然后在子组件通过this.props.xxx调用就可以了. 二.子组件传值给父组件 子组件 ...
- React 组件间通信
https://jsfiddle.net/69z2wepo/9719/ <script src="https://facebook.github.io/react/js/jsfiddl ...
- React独立组件间通信联动
React是现在主流的高效的前端框架,其官方文档 http://reactjs.cn/react/docs/getting-started.html 在介绍组件间通信时只给出了父子组件间通信的方法,而 ...
- React 精要面试题讲解(二) 组件间通信详解
单向数据流与组件间通信 上文我们已经讲述过,react 单向数据流的原理和简单模拟实现.结合上文中的代码,我们来进行这节面试题的讲解: react中的组件间通信. 那么,首先我们把看上文中的原生js代 ...
- [转] React 中组件间通信的几种方式
在使用 React 的过程中,不可避免的需要组件间进行消息传递(通信),组件间通信大体有下面几种情况: 父组件向子组件通信 子组件向父组件通信 跨级组件之间通信 非嵌套组件间通信 下面依次说下这几种通 ...
随机推荐
- ubuntu16.04安装pycharm
Ubuntu16.04下,默认安装了python2.7和python3.5,在终端下,输入“Python” 或“python3”可查看具体版本. 1.安装PyCharm前,先配置PyCharm的JD ...
- redisi应用--布隆过滤器
但是如果我们想知道某一个值是不是已经在 HyperLogLog 结构里面了,它就无能为力了,它只提供了 pfadd 和 pfcount 方法,没有提供 pfcontains 这种方法.
- 对弈的C++学习笔记
2018-07-11上传 一:从C到C++ 1.C++新类型 bool 判断真假 占用一个字节 if(条件) 真1或者假 0 bool 类型的取值 true false ...
- Python第四章(北理国家精品课 嵩天等)
一.程序的分支结构 二.身体质量指数BMI #CalBIv1.py height,weight = eval((input("请输入身高(米)和体重\(公斤)[逗号隔开]:"))) ...
- 精进之路之JMM
JMM (Java Memory Model) java内存模型 Java内存模型的抽象 Java线程之间的通信由Java内存模型(本文简称为JMM)控制,JMM决定一个线程对共享变量的写入何时对另一 ...
- flock
为了确保操作的有效性和完整性,可以通过锁机制将并发状态转换成串行状态.作为锁机制中的一种,PHP的文件锁也是为了应对资源竞争.假设一个应用场景,在存在较大并发的情况下,通过fwrite向文件尾部多次有 ...
- windows下端口占用处理工具
一.通用方法 经常,我们在启动应用的时候发现系统需要的端口被别的程序占用,笔者在最近使用tomcat时,老是会遇到这种端口占用的问题,如何知道谁占有了我们需要的端口,很多人都比较头疼,以下是通用方法: ...
- TP5 数据库迁移工具 migrate 教程
第一步: 安装compose,不赘述,安装详情可百度或查看https://pkg.phpcomposer.com/#how-to-install-composer 第二步: 通过 composer ...
- vs2017 创建虚拟目录失败 http//locXXXXXX,vs2015 无法访问IIS源数据
两个版本ide打开的错误提示不一样,但是一个解决都解决了 这个问题折磨了我接近五个小时 终于找到了解决方案,在百度上面搜的都没什么鸟用,最终还是在stackoverflow找到了解决方案,附上连接,虽 ...
- 神州数码标准访问控制列表配置(ACL)
实验要求:熟练掌握标准访问控制列表配置方法 拓扑如下 R1 enable 进入特权模式 config 进入全局模式 hostname R1 修改名称 interface s0/1 进入端口 ip ad ...