React学习(十一)之兄弟组件间传值

原理

React传递数据是单向数据流,两个组件必须有关系才可以传值。

而兄弟组件间并无直接关系,所以需要借助父组件。

兄弟组件传值原理

简单的逻辑是这样:子组件1传值给父组件,父组件再传给子组件2。

  1. 子组件1通过函数参数传值给父组件。
  2. 父组件利用子组件1传来的值改变自身state中的某个值。
  3. 由于父组件将自身state的那个值传给子组件2,而现在state发生改变 ,子组件2会重新渲染,实现子组件1传值到

这里用到了state更新dom的知识,不知道的可以看看。前边的文章或百度。

代码实现

现有三个组件,父组件App,子组件1Header,子组件2HomeHomeHeader小2岁。

实现功能:改变Header的年龄,且同步更新Home的年龄。

App.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import React, { Component } from 'react'; //固定写法
import Header from './components/Header';
import Home from './components/Home';

class App extends Component { //ES6写法

constructor(){
super();
this.state={
homeAge:10
}
}

onGreet(headerAge){ //父组件定义回调函数
alert("App:Header is"+headerAge+"years old!");
this.setState({
homeAge: headerAge-2
})
}

render() {
const user={ //定义一个对象,传给子组件Header
name: "Anna",
hobbies: ["Sports", "Reading"]
}
return (
<div>

<div>
<Header greet={this.onGreet.bind(this)} name={"Max"} age={12} user={user}>
<p>I am Header's children</p>
</Header>
</div>

<div>
<h1>I am App</h1>
</div>

<div>
<Home homeAge={this.state.homeAge}/>
</div>
</div>
);
}
}

export default App;

Header.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import React, { Component } from 'react'; //固定写法
import PropTypes from 'prop-types';

class Header extends Component { //ES6写法

constructor(props){
super(props); //执行父类构造方法
this.state={
age:props.age
}
//this.age=this.props.age;
}

onMakeOrder(){
this.setState({
age:this.state.age+3
})
//this.age+=3;
console.log(this); //显示当前Header类的对象
}

handleGreet(){
this.props.greet(this.state.age);
}

render() {
//console.log(this.props); //显示父组件传来的参数
return (
<div>
<h1>I am Header</h1>

<div>
props'name is {this.props.name},my age is {this.state.age}
</div>

{/*<button onClick={() => this.onMakeOrder()} className="btn btn-primary">make me older</button>*/}
<button onClick={this.onMakeOrder.bind(this)} className="btn btn-primary">
make me older
</button>

<br />

<button onClick={this.handleGreet.bind(this)} className="btn btn-primary">
告诉App我几岁
</button>

<div>
<h4>props'hobbies如下:</h4>
<ul>
{this.props.user.hobbies.map((hobby,i) => <li key={i}>{hobby}</li>)}
</ul>
</div>

<div>props's children如下:{this.props.children}</div>

</div>
);
}
}

Header.propTypes={
name: PropTypes.string,
age: PropTypes.number,
user: PropTypes.object,
greet: PropTypes.function,
children: PropTypes.element.isRequired
}

export default Header;

Home.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React, { Component } from 'react'; //固定写法

class Home extends Component { //ES6写法
render() {
let content="";
let flag=false;
if(flag){
content="cbh";
}
else{
content="cxy";
}

return (
<div>
<h1>I am Home</h1>
动态数据:{content}
<h1>I am {this.props.homeAge} year's old</h1>
</div>
);
}
}

export default Home;

具体过程

两个子组件本来就是12岁和10岁,无法查看传值效果。

所以先点击makeolder按钮,可以看到Header年龄变为15。

再点击告诉App我几岁按钮。

子组件1Header通过一个回调函数将自己的年龄传给父组件App,父组件再用Header传来的年龄更新自己的state;

由于父组件App给子组件2Home传的参数是state中的一个值,所以子组件2变化的部分会重新渲染,实现子组件1传值给子组件2。

作者:@臭咸鱼

本文为作者原创,转载请注明出处:https://chouxianyu.github.io

欢迎转发和评论!