react兄弟组件父子组件间该如何通信?
1、总的流程
这里,我们先来谈谈在仅仅使用react的情况下,组件间通信的流程
1. 父组件传递消息到子组件
2. 子组件传递消息到父组件
3. 兄弟组件间的消息传递
1、父组件传递消息到子组件
一般情况为:父组件中使用了子组件,然后子组件的props属性被父组件的state赋值,这样,我们在子组件中使用this.props就能获取到父组件用来赋值的state,也就获取到了父组件要传递的信息。
2、举例说明
我现在创建一个父组件Parents
创建两个子组件:Children1,Children2
然后将Children1,Children2嵌套进入Parents中,然后渲染Parents
--------------------------------------------------------------
Children1 代码如下:
import React, { Component } from 'react';
let Children1_css = {
border: '5px solid blue',
}
class Children1 extends Component {
render() {
return (
<div style={ Children1_css }>
<h1>我是子组件 Children1</h1>
<h1>父组件传来的值为:{ this.props.f1 }</h1>
</div>
);
}
}
export default Children1;
-----------------------------------------------------------------
Children2 代码如下:
import React, { Component } from 'react';
let Children2_css = {
border: '5px solid yellow',
}
class Children2 extends Component {
render() {
return (
<div style={ Children2_css }>
<h1>我是子组件 Children2</h1>
<h1>父组件传来的值为:{ this.props.f2 }</h1>
</div>
);
}
}
export default Children2;
------------------------------------------------------------
Parents代码如下:
import React, { Component } from 'react';
import Children1 from './Children1'
import Children2 from './Children2'
let Parents_css = {
border: '10px solid red',
}
class Parents extends Component {
constructor(props) {
super(props);
//初始化state
this.state = {
v1: "我是父组件中的v1",
v2: "我是父组件中的v2",
}
}
render() {
return (
<div>
<h1>我是父组件 Parents</h1>
<div style={ Parents_css }>
<Children1 f1={ this.state.v1 } />
<Children2 f2={ this.state.v2 } />
</div>
</div>
);
}
}
export default Parents;
-----------------------------------------------------
渲染代码如下
import React from 'react';
import ReactDOM from 'react-dom';
import Parents from './reactSendMessage/Parents';
ReactDOM.render(<Parents />, document.getElementById('root'));
3、解释:
我在父组件中使用两个孩子组件时,分别给两个孩子组件赋值了属性f1,f2,
并且这两个属性的值为父组件中的state中的v1,v2.
然后我在两个孩子组件中通过this.props.f1,this.props.f2的方式,得到父组件传递过来的值。从而达到父组件向子组件通信的目的
浏览器运行结果如下:
1、父向子通信我们已经知道了,那么子到父怎么通信呢?子组件如果要传递信息到父组件里那该怎么办呢?
其实形式差不多,仍然是先父组件向子组件的props赋值,然后子组件中再通过this.props获取到父组件传递过来的值,
唯一不同的是,此时父组件传递到子组件中的不再是像v1,v2那样的常量值,而是一个函数,一个专用于通信的函数。并且这个函数是属于父组件的,而不是属于父组件的state的,
这个函数由于是定义在父组件里面,所以可以直接通过他对父组件的state进行操作,但是偏偏它又被赋值给了子组件的props,由子组件来调用,换句话说这个函数就充当了一个父子间的沟通桥梁,【它由父组件定义,由子组件使用,子组件想要传递任何消息都可以通过这个函数来告诉父组件,父组件接收后,做出相应的响应】
此时也就意味着,如果子组件想要发一个消息到父组件,只需要调用下这个函数,传递一个参数,父组件就能知道了,并响应子组件请求。
2、代码实例
我在父组件中定义一个函数,changeTitle,它接收一个参数,用来设置父组件的标题。然后赋值给子组件Children1的fn属性(注意:在es6语法中,给子组件属性赋值时,父组件函数一定要绑定父组件的this对象,否则子组件在调用此函数时会报错),然后子组件通过this.props调用此函数,来与父组件通信【子组件此时给此参数设置任意值,父组件的标题就会被修改为相应值。】
父组件Parents代码
import React, { Component } from 'react';
import Children1 from './Children1'
import Children2 from './Children2'
let Parents_css = {
border: '10px solid red',
}
class Parents extends Component {
constructor(props) {
super(props);
//初始化state
this.state = {
title: "我是父组件 Parents",
v1: "我是父组件中的v1",
v2: "我是父组件中的v2",
}
}
changeTitle(titlev) {
// alert("点我改变标题");
this.setState({
title: titlev,
});
}
render() {
return (
<div>
<h1>{ this.state.title }</h1>
<div style={ Parents_css }>
<Children1
f1={ this.state.v1 }
fn={ this.changeTitle.bind(this) } />
<Children2 f2={ this.state.v2 } />
</div>
</div>
);
}
}
export default Parents;
---------------------------------------------------
子组件Children1代码
import React, { Component } from 'react';
let Children1_css = {
border: '5px solid blue',
}
class Children1 extends Component {
click() {
this.props.fn("我是子组件设置的标题,666666"); //在点击事件里面调用父组件传递来的通信函数,可以发出让父组件修改自己标题的信息
}
render() {
return (
<div style={ Children1_css }>
<h1>我是子组件 Children1</h1>
<h1>父组件传来的值为:{ this.props.f1 }</h1>
<button onClick={ this.click.bind(this) }> {注释:这里绑定点击事件}
点击我能修改父组件的标题哦
</button>
</div>
);
}
}
export default Children1;
----------------------------------------
3、运行结果如下
4、注意事项:
在子组件向父组件传值的过程中,要注意的几点我再提一下
1. 现在大家基本都是使用的es6语法,而es6语法中,我们将父组件的函数赋值给子组件时,一定要记住绑定到父组件的this对象中,否则会报错。【这里提一句,通过箭头函数的方式也可以达到绑定this的目的,有兴趣可以自己研究下】
2. 子组件使用父组件传递来的函数通信时,一定不要直接将此函数属性绑定在子组件的onClick中,而是应该让子组件的onclick绑定函数a.然后在函数a中调用父组件传递来的函数属性。
1、在纯react中,兄弟组件间无法直接传值,需要通过父组件进行中转。换句话说,
兄弟组件传值的流程是:
子组件1---》父组件---》子组件2【其中子组件1和2是兄弟组件】
这样兄弟组件就达到了通信的目的。
2、现在我来进行代码示例
其实这个非常简单,刚刚我是用的子组件1来向父组件直接通信的,然后父组件接收到了子组件1的信息,做出响应修改自己的标题,
现在我们只需要改变下就可以了,当父组件接收到消息后,不是去修改自己的标题,而是去修改子组件2的内容,也就是子组件1发出一个消息后,子组件1就修改了,(兄弟间的通信)
父组件代码:
import React, { Component } from 'react';
import Children1 from './Children1'
import Children2 from './Children2'
let Parents_css = {
border: '10px solid red',
}
class Parents extends Component {
constructor(props) {
super(props);
//初始化state
this.state = {
title: "我是父组件 Parents",
v1: "我是父组件中的v1",
v2: "我是父组件中的v2",
}
}
change_xiongdi_Title(v2_titlev = "默认值") {
// 改变兄弟title
this.setState({
v2: v2_titlev,
});
}
render() {
return (
<div>
<h1>{ this.state.title }</h1>
<div style={ Parents_css }>
<Children1
f1={ this.state.v1 }
fn={ this.change_xiongdi_Title.bind(this) } />
<Children2 f2={ this.state.v2 } />
</div>
</div>
);
}
}
export default Parents;
------------------------------------------------------------------------
3、在浏览器里面的运行效果如下
1、在仅仅使用react的情况下,组件间通信总的流程为
1. 父组件传递消息到子组件,
通过:父-----(state)------》子props
2. 子组件传递消息到父组件,
通过:父------(function)---》子props-------(调用此函数)-------》父
3. 兄弟组件间的消息传递,
通过:父------(function)---》子props----》父------》另一个子
ok,看到没,一层一层是存在依赖关系的,必须要先父传子,才能子传父。然后能够子传父,才能子传子(兄弟间通信),并且每一个流程都是接着上一个流程在增加些内容就是了。(在这种通信模式下是这样的)
注意下:
我们这里说的父子,并不像面向对象语言(如java,c#)那样存在继承关系,react中,子组件与父组件并不存在继承关系,子组件没有继承父组件,子组件中不包含父组件里面的属性方法等。子组件只是父组件的一个组成部分。
2、最后,如果你想简单的了解下用react开发的整个流程的话,(从无到有最后部署到服务器,然后发布,然后运营),可以去阅读我前面写的一篇文章