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})&nbsp;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兄弟、父子元素之间的通信的更多相关文章

  1. React 学习(六) ---- 父子组件之间的通信

    当有多个组件需要共享状态的时候,这就需要把状态放到这些组件共有的父组件中,相应地,这些组件就变成了子组件,从而涉及到父子组件之间的通信.父组件通过props 给子组件传递数据,子组件则是通过调用父组件 ...

  2. 【转】vue父子组件之间的通信

    vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...

  3. React中父子组件间的通信问题

    1.https://blog.csdn.net/sinat_17775997/article/details/59103173 (React中父子组件间的通信问题)

  4. vue的父子组建之间的通信(-),基于props和$emit之间的传递

    对于vue而言,以为其核心思想为前端组建化.所以组建之间的通信必不可少. 相信接触过Angularjs的童鞋都知道angularjs的控制器之间的通信机制. 1:父传子:官方的$broadcast() ...

  5. React之父子组件之间传值

    1.新增知识点 /** React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. 父子组件:组件的相互调用中,我们把调 ...

  6. React native和原生之间的通信

    RN中文网关于原生模块(Android)的介绍可以看到,RN前端与原生模块之 间通信,主要有三种方法: 1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript. 2)使 ...

  7. vue2.0 父子组件之间的通信问题

    概要: 父组件向子组件通信:props属性 子组件向父组件通信:$emit()触发事件,$on()监听事件 在 vue 1.0 中可以使用$dispatch 和 $broadcast来实现 向上派发事 ...

  8. vue非父子组件之间的通信

    https://www.cnblogs.com/chengduxiaoc/p/7099552.html   //vm.$emit( event, arg ) //触发当前实例上的事件 //vm.$on ...

  9. Phaser游戏框架与HTML Dom元素之间的通信交互

    本想按照PHASER的HTML Dom元素官方实例:http://labs.phaser.io/index.html?dir=game%20objects/dom%20element/&q=  ...

随机推荐

  1. JProfiler进行Java运行时内存分析

    原文地址:https://www.cnblogs.com/onmyway20xx/p/3963735.html 在最近的工作中,通过JProfiler解决了一个内存泄漏的问题,现将检测的步骤和一些分析 ...

  2. Spark 准备篇-环境搭建

    本章内容: 待整理 参考文献: 学习Spark——环境搭建(Mac版) <深入理解SPARK:核心思想与源码分析>(前言及第1章) 搭建Spark源码研读和代码调试的开发环境 Readin ...

  3. ASP.NET CORE下用盛派微信SDK取微信openid

    用CORE做项目用到微信的相关东西,听说那个盛派微信SDK很火,自己弄了下,只是简单的用用,用户访问页面取微信openid

  4. Java知多少(21)this关键字详解

    this 关键字用来表示当前对象本身,或当前类的一个实例,通过 this 可以调用本对象的所有方法和属性.例如: public class Demo{ public int x = 10; publi ...

  5. Java知多少(83)面板基础:JPanel和JScrollPane

    面板有两种,一种是普通面板(JPanel),另一种是滚动面板(JScrollPane). JPanel 面板是一种通用容器,JPanel的作用是实现界面的层次结构,在它上面放入一些组件,也可以在上面绘 ...

  6. [js] 处理字符串换行造成的json解析失败

    需求:从数据库某个字段取出字符串出来,转为json,结果发现报错为 解析失败,发现是因为取出的字符串换行导致,现在需要将字符串里面的换行替换为'',使字符串可依成功解析成json对象. 技术:依靠re ...

  7. tensflow自定义损失函数

    tensflow 不仅支持经典的损失函数,还可以优化任意的自定义损失函数. 预测商品销量时,如果预测值比真实销量大,商家损失的是生产商品的成本:如果预测值比真实值小,损失的则是商品的利润. 比如如果一 ...

  8. U3D 垂直同步

    Unity3D中新建一个场景空的时候,帧速率(FPS总是很低),大概在60~70之间.一直不太明白是怎么回事,现在基本上明白了.我在这里解释一下原因,如有错误,欢迎指正.在Unity3D中当运行场景打 ...

  9. Elasticsearch 学习之携程机票ElasticSearch集群运维驯服记(强烈推荐)

    转自: https://mp.weixin.qq.com/s/wmSTyIGCVhItVNPHcH7nsA 一.整体架构 为什么采用ES作为搜索引擎呢?在做任何事情的时候,不要一上来就急着了解怎么做这 ...

  10. element的form表单中如何一行显示多el-form-item标签

    效果图: HTML代码: <script src="//unpkg.com/vue/dist/vue.js"></script> <script sr ...