React兄弟、父子元素之间的通信
React兄弟、父子元素之间的通信
React元素之间的通信主要由下面几种方式
1、 Redux
2、 EventEmitter
3、 通过props进行通信(需要有嵌套关系)
子元素到父元素
父子元素之间的通信主要靠props,这个方法既简单,又好用,所以可以使用这种方法的时候就直接用好了。
首先有这样的一个React DOM结构:
<div className="passage">
<NavBar />
<Passage />
</div>
渲染外层的div元素的时候,需要进行两个子组件的渲染,其中Passage组件的加载内容取决于NavBar当前的内容或者被点击后的内容,这里可以首先实现父元素和NavBar之间的通信过程,设置一个句柄,来帮助进行通信。
constructor (props) {
super(props);
this.state = {
currentPassage: ""
}
this.refreshCurrentPassage = this.refreshCurrentPassage.bind(this);
}
refreshCurrentPassage(cp) {
this.setState({
currentPassage: cp
});
}
上面的refreshCurrentPassage函数是这个通信过程的关键,我们将这个函数绑定当前父元素的this对象,并且将这个函数通过props传递给子元素:
render() {
return (
<div className="passage">
<NavBar refreshCurrentPassage={this.refreshCurrentPassage} />
<Passage currentPassage={this.state.currentPassage}/>
</div>
);
}
子元素在其生命周期的componentDidMount阶段通过ajax获取当前页信息并且调用这个函数,将消息传递给父元素,这里需要注意React的生命周期,componentDidMount在官方给出的解释是:
Invoked once, only on the client (not on the server), immediately after the initial rendering occurs.
注意是在初始化渲染之后执行一次的。如果你还有其他特殊需求的话可以在其他阶段来调用这个函数。
class NavUl extends React.Component {
constructor (props) {
super(props);
this.state = {
passage: []
}
}
componentDidMount() {
//在ajax请求成功之后调用一次更新父元素状态的函数,来完成一次父子元素之间的通信
$.ajax({
url: "../resources/data/passage.json",
success: (data) => {
this.setState({
passage: data.passages
});
this.props.refreshCurrentPassage(data.passages[0].passageName);
}、
});
}
render() {
let liArray = [];
this.state.passage.forEach((value,index) => {
let liEle = <li key={value.passageName.toString()}>
<a>
{value.passageName}({value.letterNum}) author:{value.author}
</a>
</li>
liArray.push(liEle);
});
return (
<ul>
{liArray}
</ul>
)
}
}
class NavBar extends React.Component {
constructor (props) {
super(props);
}
render() {
return (
<nav>
<NavUl refreshCurrentPassage={this.props.refreshCurrentPassage}/>
</nav>
);
}
}
父元素到子元素
父元素到子元素的状态通信更加简单了,可以直接使用props来进行传递。
//父元素的render函数
render() {
return (
<div className="passage">
<NavBar refreshCurrentPassage={this.refreshCurrentPassage} />
<Passage currentPassage={this.state.currentPassage}/>
</div>
);
}
通过将自己的state的currentPassage属性传递给子元素的一个属性,也就是props对象,来告诉子元素加载某个模块。
class Passage extends React.Component {
constructor (props) {
super(props);
this.state = {
passage: ""
}
}
//子元素通过自己的this.props对象来进行访问,可以直接得到父元素传递的消息
componentWillReceiveProps (nextProps) {
let passageName = nextProps.currentPassage;
passageName = passageName.toLowerCase().replace(" ", "");
$.ajax({
url: "../resources/data/" + passageName + ".json",
success: (data) => {
this.setState({
passage: data.passageContent
});
}
});
}
render() {
return (
<article>
<p>
{this.state.passage}
</p>
</article>
);
}
}
兄弟元素之间
上面的两个部分组合起来刚好就完成了兄弟元素之前的通信,其中一个子元素通过调用父元素传递过来的函数this.props.refreshCurrentPassage来修改父元素状态,然后在父元素状态修改之后,另外一个子元素的this.props会发生变化,从而触发重新渲染。这里需要注意的是React组件的声明周期,父元素到子元素通信由于可能需要多次渲染,所以使用了声明周期中的componentWillReceiveProps阶段来进行内容加载。在官方文档中是这么介绍这个阶段的:
Invoked when a component is receiving new props. This method is not called for the initial render.
也就是在一个组件接收了新的属性(props)触发的,这个方法不会在初始化渲染的时候触发。并且这个阶段还可以访问修改前的props对象。
React兄弟、父子元素之间的通信的更多相关文章
- React 学习(六) ---- 父子组件之间的通信
当有多个组件需要共享状态的时候,这就需要把状态放到这些组件共有的父组件中,相应地,这些组件就变成了子组件,从而涉及到父子组件之间的通信.父组件通过props 给子组件传递数据,子组件则是通过调用父组件 ...
- 【转】vue父子组件之间的通信
vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...
- React中父子组件间的通信问题
1.https://blog.csdn.net/sinat_17775997/article/details/59103173 (React中父子组件间的通信问题)
- vue的父子组建之间的通信(-),基于props和$emit之间的传递
对于vue而言,以为其核心思想为前端组建化.所以组建之间的通信必不可少. 相信接触过Angularjs的童鞋都知道angularjs的控制器之间的通信机制. 1:父传子:官方的$broadcast() ...
- React之父子组件之间传值
1.新增知识点 /** React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. 父子组件:组件的相互调用中,我们把调 ...
- React native和原生之间的通信
RN中文网关于原生模块(Android)的介绍可以看到,RN前端与原生模块之 间通信,主要有三种方法: 1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript. 2)使 ...
- vue2.0 父子组件之间的通信问题
概要: 父组件向子组件通信:props属性 子组件向父组件通信:$emit()触发事件,$on()监听事件 在 vue 1.0 中可以使用$dispatch 和 $broadcast来实现 向上派发事 ...
- vue非父子组件之间的通信
https://www.cnblogs.com/chengduxiaoc/p/7099552.html //vm.$emit( event, arg ) //触发当前实例上的事件 //vm.$on ...
- Phaser游戏框架与HTML Dom元素之间的通信交互
本想按照PHASER的HTML Dom元素官方实例:http://labs.phaser.io/index.html?dir=game%20objects/dom%20element/&q= ...
随机推荐
- Effective Java 第三版——44. 优先使用标准的函数式接口
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 【emWin】例程十八:jpeg图片显示
说明:1.将文件拷入SD卡内即可在指定位置绘制jpeg图片文件,不必加载到储存器. 由于jpeg格式文件显示时需要进行解压缩,耗用动态内存,iCore3所有模块受emwin缓存的限制,jpeg ...
- opencv 基本使用
1.下载opencv库 https://opencv.org/ 下载后文件: 双击提取文件到指定路径: * 下载winpack版本可以省去自己编译的步骤,下载后无需安装双击可以直接提取文件到指定目录: ...
- Java知多少(97)绘图模式概述
绘图模式是指后绘制的图形与早先绘制的图形有重叠时,如何确定重叠部分的颜色.例如,后绘制的覆盖早先绘制的:或者后绘制与早先绘制的两种颜色按某种规则混合.主要有正常模式和异或模式两种:正常模式是后绘制的图 ...
- Go语言_range(范围)理解
一.Go语言中的range Go 语言中 range 关键字用于 for循环中迭代数组(array).切片(slice).链表(channel)或集合(map)的元素: 在数组和切片中它返回元素的索引 ...
- Spark学习笔记——在远程机器中运行WordCount
1.通过realy机器登录relay-shell ssh XXX@XXX 2.登录了跳板机之后,连接可以用的机器 XXXX.bj 3.在本地的idea生成好程序的jar包(word-count_2.1 ...
- QT QML 3D模型查看器
原文链接:http://amin-ahmadi.com/2018/01/28/viewing-3d-models-using-qt/ 本文使用QT Quick中的Scene3D QML类型来查看3D模 ...
- 给hmailserver添加DKIM签名
上一篇说了hmailserver如何设置反垃圾邮件功能,现在来说说如何让自己的hmailserver发出去的邮件不要被别人反垃圾了.在hmailserver的反垃圾邮件功能中有提到给垃圾评分标准,其中 ...
- NUC972---Linux驱动开发
驱动开发是嵌入式 Linux 产品开发的重要组成部分,驱动是将芯片底层与Linux应用连接起来的桥梁.驱动程序的好坏直接影响和决定着产品的稳定性,稳定的驱动程序是产品可靠性的基石. 编写 Linux ...
- 【netcore入门】在Windows IIS上部署.NET Core 2.1项目
部署之前先检查下面2个先决条件是否满足 1.安装了 IIS 模块 win7 在 控制面板→程序和功能→打开或关闭Windows功能→勾选Internet 信息服务(Internet Informati ...