背景
一次在用react写用户修改时,想着将用户基础信息和用户所属角色存储在state中,然后显示。部分代码如下,结果发现运行出来的结果和预料的不一致。这个是为什么呢??真的是纠结了半个下午。
class UserEdit {
this.state = {
initialValue : {
roleIds : []
}
}
componentDidMount() {
this.treeSelectRoles();
this.showUser(1);
this.userRolesId(1);
}
userRolesId = (id) => {
const _this = this;
const initalValue = _this.state.initialValue;
axios.patch('/backstage/users/'+id+'/roleIds')
.then(function (res) {
console.log(res.data); //[12,13]
_this.setState({
initialValue:{
...initalValue,
roleIds : res.data
}
})
})
.catch(function (err) {
message.error(err.response.data.message || '服务器异常,请稍后重试或联系管理员');
})
};
showUser = (id) => {
const _this = this;
const roleIds = _this.state.initialValue.roleIds;
axios.get('/backstage/users/'+id+'/roleIds')
.then(function (res) {
console.log(res.data); //{name:"test", email:"test@qq.com", id:1}
_this.setState({
initialValue : {
...res.data,
roleIds : roleIds
}
});
})
.catch(function (err) {
message.error(err.response.data.message || '服务器异常,请稍后重试或联系管理员');
});
};
render() {
<div>姓名:{this.state.initalValue.name}</div>
<div>邮箱:{this.state.initalValue.email}</div>
角色: {this.state.initalValue.roleIds.map(d => <div >d</div>)}
}
}
//期望值:
姓名:test
邮箱:test@qq.com
角色:12
13
//实际值
姓名:undefined
邮箱:undefined
角色:12
13
原来是因为axios异步请求的原因。这个程序实际的执行顺序是,在组件挂载完成之后先调用showUser方法,获取到的roleIds是空数组,然后给后台发送get请求,敲黑板,,获取到的initalValue值依然是初始化时的值,所以最终name和email的值都是undefined。
class UserEdit {
this.state = {
initialValue : {
roleIds : []
}
}
componentDidMount() {
this.treeSelectRoles();
this.showUser(1);
this.userRolesId(1);
}
userRolesId = (id) => {
const _this = this;
axios.patch('/backstage/users/'+id+'/roleIds')
.then(function (res) {
const initalValue = _this.state.initialValue;
console.log(res.data); //[12,13]
_this.setState({
initialValue:{
...initalValue,
roleIds : res.data
}
})
})
.catch(function (err) {
message.error(err.response.data.message || '服务器异常,请稍后重试或联系管理员');
})
};
showUser = (id) => {
const _this = this;
axios.get('/backstage/users/'+id+'/roleIds')
.then(function (res) {
const roleIds = _this.state.initialValue.roleIds;
console.log(res.data); //{name:"test", email:"test@qq.com", id:1}
_this.setState({
initialValue : {
...res.data,
roleIds : roleIds
}
});
})
.catch(function (err) {
message.error(err.response.data.message || '服务器异常,请稍后重试或联系管理员');
});
};
render() {
<div>姓名:{this.state.initalValue.name}</div>
<div>邮箱:{this.state.initalValue.email}</div>
角色: {this.state.initalValue.roleIds.map(d => <div >d</div>)}
}
}
//运行结果
姓名:test
邮箱:test@qq.com
角色:12
13
在这个程序中,我们把获取state放到请求完成之后处理,这样才能确保获取的state是最新的。
结论
因为axios的异步请求,我们在处理请求时,一定要在then之后,不然可能会出现不可预料的结果。