React中的state和props更新
github个人博客源码持续更新中。。。
在搭建个人博客的过程中,需要添加一个登陆窗体,登陆按钮和登陆表单分别在不同的组件,登陆btn在组件HeaderCustom,登陆窗体和表单在FormLogin,由登陆btn控制FormLogin的显示和隐藏,利用Redux进行状态管理。
HeaderCustom
onLogin = () => {
this.setState({
visible: true
},()=>{
console.log("onLogin_state");
console.log(this.state);
});
}
render(){
return(....
<Menu.Item key="7" className="" style={ { lineHeight: '64px', position: "absolute", right: '0px', top: "0px" } }>
<span onClick={ this.onLogin }> <Icon type="user" style={ { fontSize: 16, color: '#1DA57A' } }/>{ this.props.username } </span>
<UserLoginFrom visible={ loginFormVisible }></UserLoginFrom>
</Menu.Item>
...);
}
const mapStateToProps = (state) => {
var adminAccess = state.reducer_login.adminAccess;
var loginVisible = state.reducer_login.loginFormVisible;
return {
adminAccess: adminAccess,
loginFormVisible: loginVisible
}
}
FormLogin
handleOk = () => {
this._loginCheck()
this.setState({
loading: true
});
setTimeout(() => {
this.setState({
visible: false
});
}, 3000);
this.props.changeLoginVisible({
loginFormVisible:false
})
}
handleCancel() {
this.setState({
visible: false
});
this.props.changeLoginVisible({
loginFormVisible:false
})
}
render() {
const {getFieldDecorator} = this.props.form;
const {visible, loading} = this.state;
return (
<Modal style={ { textAlign: "center" } } destroyOnClose={true} cancelText="取消" okText="登陆" visible={ visible } title="管理端登陆验证" onOk={ this.handleOk.bind(this) } onCancel={ this.handleCancel.bind(this) }>
<Form onSubmit={ this.handleSubmit } className="login-form">
......
</Form>
</Modal>
);
}
const mapDispatchToProps = (dispatch) => {
return {
changeAccess: (assessToAdmin) => {
dispatch(changeAdminAccess(assessToAdmin))
},
changeLoginVisible:(loginFormVisible)=>{
dispatch(closeUserLoginForm(loginFormVisible))
}
}
}
解决方法1
在实施的过程中,遇到了setState方法和props更新的困扰,由于每次关闭窗体后,传递给HeaderCoustom的props为 loginFormVisible:false,出现了再次点击登陆按钮时窗体不显示的情况,经过分析才发现,props对象没有发生改变,render方法当然不会自动执行,故解决的办法是在props对象中加入时间戳:
const mapStateToProps = (state) => {
var adminAccess = state.reducer_login.adminAccess;
var loginVisible = state.reducer_login.loginFormVisible;
//加入 key:(new Date()).getTime() 时间戳 每次传入的Props对象都不一样 组件都会重新渲染一次
return {
adminAccess: adminAccess,
loginFormVisible: loginVisible,
key:(new Date()).getTime()
}
}
在实施的过程中,还发现了setState执行后,state对象不会立马改变,而是先执行render渲染后,才发生变化的。
onLogin = () => {
this.setState({
visible: true
},()=>{
console.log("onLogin_state");
console.log(this.state);//回调函数函数在render执行后再触发,此处打印的是变化后的state
});
console.log(this.state);//打印state变化前的对象
}
解决方法2
放发一用到了redux刷新父级组价的props,这在深层次的嵌套中是最有效的传递状态的方法,但是在直接嵌套的父子组件中,感觉有些大材小用,父级组件可以直接绑定方法传递给子组件。
父级组件
onLoginClose = () => {
this.setState({
visible: false
}, () => {
console.log("onLogin_close");
console.log(this.state);
});
}
render(){
...
<Menu.Item key="7" className="" style={ { lineHeight: '64px', position: "absolute", right: '0px', top: "0px" } }>
<span onClick={ this.onLogin }> <Icon type="user" style={ { fontSize: 16, color: '#1DA57A' } }/>{ this.props.username } </span>
<UserLoginFrom visible={ loginFormVisible } onClose={ this.onLoginClose.bind(this) }></UserLoginFrom>
</Menu.Item>
}
...
子组件
handleCancel() {
this.setState({
visible: false
});
console.log(this.props.onClose)
this.props.onClose();
}
将onClose传递给子组件 ,子组件状态改变时,反馈给父级组件改变父级自身的状态。