之前有写过一些关于react的基础的Demo。现在说一说组件之间怎么通信。
github
上有相应的代码参考:https://github.com/RealAndMe/react-demo
1. 概念
React主要是用来构建用户界面的JavaScript库。它的特点:
- 单向响应数据流
- 组件。代码可以复用。
- 高效。React是在虚拟DOM上进行操作然后渲染到真实DOM上的。
- JSX。这是JavaScript的语法扩展。
2. React组件之间的通信
react 组件之间的交流可以分成 4 种:
- 【父组件】向【子组件】传值
- 【父组件】向【孙组件】传值
- 【子组件】向【父组件】传值
- 兄弟组件之间传值(没有任何嵌套关系的组件)
3. 数据从父组件到子组件
父组件给子组件传值,也就是子组件调用父组件。
var Father = React.createClass({
render: function() {
return (
<div>
<Child01 name={this.props.name} />
<Child02 site={this.props.site} />
</div>
);
}
});
var Child01 = React.createClass({
render: function() {
return (
<h1>{this.props.name}</h1>
);
}
});
var Child02 = React.createClass({
render: function() {
return (
<a href={this.props.site}>
{this.props.site}
</a>
);
}
});
ReactDOM.render(
<Father name="父组件给子组件传参" site=" http://www.baidu.com" />,
document.getElementById('contain')
);
上述代码中,父组件是<Father />
。有两个子组件<Child01 />
<Child02 />
。父组件向子组件传值,子组件通过调用 this.props
来获取父组件的值。
查看(demo14)
还有另一个例子在 github
上的 demo14 中的 index2.html ,也是关于数据从父组件传到子组件的。
4. 数据从父组件到孙组件##
//父组件
var Father = React.createClass({
getInitialState: function(){
return {
msg: "start"
}
},
componentDidMount: function(){
var t = this;
setTimeout(function(){
t.setState({
msg: "end"
});
},1000);
},
render: function() {
return (
<div>
<Child msg={this.state.msg}/>
</div>
);
}
});
//子组件
var Child = React.createClass({
render: function(){
return(
<div>
<h1>{this.props.msg}</h1>
<ChildChild {...this.props} />
</div>
)
}
});
//孙组件
var ChildChild = React.createClass({
render: function(){
return(
<h1>{this.props.msg}</h1>
)
}
})
ReactDOM.render(<Father />,document.getElementById("contain"));
上述代码中,是父组件向孙组件传参。通过 ...运算符
将父组件的信息,以更加简洁的方式传递给孙组件。上级组件 props 与 state 的改变,会导致组件本身及其子组件的生命周期改变。
查看(demo15)
注意: 如果组件嵌套层太深,那么
props
传值就变得没有那么高效。所以建议尽可能的减少组件的层次,结构简单清楚较好。
4. 数据从子组件到父组件##
//父组件
var Father = React.createClass({
getInitialState: function(){
return {
checked: false
}
},
onCheck: function(newState){
this.setState({checked: newState});
},
render: function() {
var isCheck = this.state.checked?"yes":"no";
return (
<div>
<div>父组件的状态:{isCheck}</div>
<Child text="子组件勾选改变状态:"
isCheck={this.state.checked}
callFather={this.onCheck}/>
</div>
);
}
});
//子组件
var Child = React.createClass({
getInitialState: function(){
return{
checked: this.props.inCheck
};
},
onChangeState: function(){
var newState = !this.state.checked;
this.setState({
checked : newState
});
//注意,需要调用父组件的方法实现数据从子组件传给父组件
this.props.callFather(newState);
},
render: function(){
//子组件从父组件获取值
var text = this.props.text;
//子组件自身的状态
var checked = this.state.checked;
return(
<div>{text}<input type="checkbox" checked={checked} onClick={this.onChangeState}/></div>
)
}
});
ReactDOM.render(<Father />,document.getElementById("contain"));
上面介绍过,父组件可以通过 props
的方式,自上而下向子组件或是孙组件通讯,而子组件向父组件通讯也可以通过 props
,只是父组件传递的是作用域为父组件本身的函数,子组件调用该函数,将子组件需要传递的值作为参数,传给父组件的作用域中。
上述代码中,父组件 <Father />
它本身有一个函数 onCheck()
,子组件 <Child />
通过 this.props
调用该函数,然后将传递的信息通过 newState
作为参数传给父组件。
查看(demo16)
还有另一个例子在 github
上的 demo16 中的 index2.html ,也是关于数据从子组件到父组件,不同的是,它是多个子组件调用同一个回调函数。
5. 兄弟组件之间传值
拥有同一个父组件,但是没有直接关联关系的两个组件就可以称之为兄弟组件。
比如有两个兄弟组件<Child01 />
<Child02 />
,他们拥有同一个父组件 <Father />
,如果我们由 <Child01 />
向 <Child02 />
进行通讯,那么我们可以通过 <Child01 />
先向 <Father />
通讯,然后通过 <Father />
向 <Child02 />
通讯。这种方法就是结合了上述的子组件和父组件之间的通讯
来完成的。
//父组件
var Father = React.createClass({
getInitialState: function(){
return{
msg: "兄弟组件未更新"
}
},
transferMsg: function(){
this.setState({msg:"兄弟组件沟通成功"});
},
render: function(){
return(
<div>
<p>兄弟组件之间进行通讯</p>
<Child01 transferMsg={this.transferMsg}/>
<Child02 text={this.state.msg} />
</div>
)
}
});
//子组件01
var Child01 = React.createClass({
render: function(){
return(
<button onClick={this.props.transferMsg}>更新兄弟组件</button>
)
}
});
//子组件02
var Child02 = React.createClass({
render: function(){
return(
<div>{this.props.text}</div>
)
}
});
ReactDOM.render(<Father />,document.getElementById("contain"));
上述代码中,<Child01 />
通过 this.props
回调 <Father />
中的 transferMsg()
函数方法,然后 <Father />
将信息传递给 <Child02 />
。
查看(demo17)
有道云笔记参考:
http://note.youdao.com/noteshare?id=9905a9dc8d428c4e570a738279708a98&sub=6964AD2CE4C849C4A41A2749A69BB940