在经历了许多的html+css+js的传统网页制作之后,最近开始上手react了。学了一点语法之后就开始了react的项目,
然而事情不总是一帆风顺的。刚上手的时候,项目的进度就是一团糟。各种迷之bug纷至沓来,在这里真的要提醒诸位,在写react es6语法的时候,html结构中的dom事件千万要注意大小写,比如html结构中的onclick事件,这个在html页面中是这样写的,然而在es6里面就只能用onClick了,否则会影响组件的生成。
好了,话不多说,我们进入正题。
react相邻组件间是怎么通信的?大家应该都知道react在生成组件以后只有setState方法能引起组件重新渲染,然而在相邻组件之间,同级组件是不可能影响到另一个组件的setState方法的。也就是说,如果我要实现qq登录(安卓端)的效果(修改账号同时修改头像),就目前来看是不可能的。
为此,react给我们提供了一个方法:状态提升
原理很简单,就是将同级的需要相互通信的组件写到一个父组件中,然后给两个子组件分别传递不同的参数,包括改变State的函数和State中改变的属性。
换句话说,就是重新渲染父组件以达到我们想要的效果。
//子组件1
//头像url默认为user.png,只要输入了uid,则获取当前用户的头像url,并更新这个组件
export class UserAvatar extends Component{
constructor(props){
super(props);
}
componentDidMount(){
console.log(this.props.imageurl);
console.log("avatar init")
}
//下面接收父组件传递过来的State参数
render() {
return (
<div className="avatar-wrapper">
this.props.imageurl} alt="头像" />
div>
)
}
}
//子组件2
export class Login extends Component{
constructor(props){
super(props);
}
componentDidMount(){
console.log(this.props.changeAva);
console.log("login init");
}
//下面接收改变状态的函数方法
render(){
return(
<div className="login-wrapper">
<div className="text-input-wrapper">
"account"/>
"text" className="text-input" maxlength="10" onBlur={this.props.changeAva.bind(this)}/>
div>
<div className="text-input-wrapper">
"password"/>
"text" className="text-input" maxlength="10"/>
div>
<div className="button-wrapper">
"button" value="登录" onClick={this.onLogin.bind(this)}/>
div>
<div className="forget-password-wrapper">"#!">忘记密码?div>
div>
)
}
onLogin(){
alert("申请授权中,请耐心等待");
}
}
//父组件
export class LoginAvatar extends Component{
constructor(){
super();
this.state={
imageUrl:"../../resource/images/avatar/user.png"
};
}
//改变状态的方法在父组件中定义
changeAvatar(){
this.setState({
imageUrl:"../../resource/images/avatar/1262283870/avatar.jpg"
})
}
render(){
return(
<div className="main-login-wrapper">
this.state.imageUrl}/>
this.changeAvatar.bind(this)}/>
div>
)
}
}
简单来说,就是父组件调用子组件时,给子组件传递相应的参数,一个用于显示,一个用户重新渲染。这就是所谓的状态提升,也因此我们能实现组件间的通信。
个人理解,如若有误,还请不吝赐教。