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= ... 
随机推荐
- 11G新特性 -- 分区表和增量统计信息
			对于分区表,优化器会在全局级别为整个表维护一份统计信息,也会在分区级别为分区表维护一份统计信息. 对于大多数分区,dml一般都是在最近的分区上执行.在11g中,数据库支持只对那些发生一定数据变化的分区 ... 
- Atitit.pagging  翻页功能解决方案专题 与 目录大纲 v3 r44.docx
			Atitit.pagging 翻页功能解决方案专题 与 目录大纲 v3 r44.docx 1.1. 翻页的重要意义1 1.2. Dep废弃文档 paip.js翻页分页pageing组件.txt1 ... 
- Atitit 数据库 标准库  sdk 函数库 编程语言 mysql oracle  attilax总结
			Atitit 数据库 标准库 sdk 函数库 编程语言 mysql oracle attilax总结 1.1. 常见的编程语言以及数据库 sql内部函数库标准化库一般有以下api1 1.2. 各个 ... 
- JPA+Hibernate 3.3  ——增删改查
			1. 查找对象 1) 用find()方法查找对象 public void getPerson(){ EntityManagerFactory factory = Persistence. ... 
- Zookeeper之Zookeeper的Client的分析【转】
			Zookeeper之Zookeeper的Client的分析 1)几个重要概念 ZooKeeper:客户端入口 Watcher:客户端注册的callback ZooKeeper.SendThread: ... 
- Oracle分割字符串 REGEXP_SUBSTR用法
			分割字符串中所有指定字符,然后成多行参数说明,参数1: 待分割字符串参数2:正则表达式参数3:起始位置,从第几个字符开始正则表达式匹配(默认为1)参数4:标识第几个匹配组,默认为1参数5:模式('i' ... 
- Vue:Vue2.0搭建脚手架
			随着Vue.js越来越火爆,更多的项目都用到Vue进行开发,在实际的开发项目中如何搭建脚手架呢?今天就来跟大家分享一下如何使用vue-cli搭建脚手架. 一.安装node.js 1.进入官网https ... 
- 【webssh】网页上的SSH终端
			[webssh] ——记两天来比较痛苦的历程 广义上来说,webssh泛指一种技术可以在网页上实现一个SSH终端.从而无需Xshell之类的模拟终端工具进行SSH连接,将SSH这一比较低层的操作也从C ... 
- Android Wifi 主动扫描 被动扫描
			介绍主动扫描,被动扫描以及连接的wifi的扫描过程 参考文档 <802.11无线网络权威指南> <80_Y0513_1_QCA_WCN36X0_SOFTWARE_ARCHITECTU ... 
- R语言reads.table 自动将字符串变成了逻辑值
			今天遇到了一个问题,文件中有一列的值为全为F, 用read.table 读取的时候,自动将F 变成了false 对于这样的转换,可以通过 colClass 参数控制 colClass 参数指定每一列的 ... 
