如果您能指出正确的方向,我将无法解决。在NavMenu.js上,我具有LogIn(两个输入和一个提交按钮,在该按钮上,我叫handleSubmit()
在handleSubmit()
中,我正在检查用户登录凭据是否有效,但是在确认登录后,我继续进行下一次访存以检查用户角色(并返回承诺)和在应用程序中的可见性
Helper.js
function getAllRoles(formName, sessionVarName) {
var roleData = [];
var roleId = sessionStorage.getItem('UserLoggedRoleId');
fetch('api/User/GetUserRole/', {
'method': 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
'body':
JSON.stringify({
'roleId': roleId,
'formName': formName
})
}).then(roleResponse => roleResponse.json())
.then(data => {
sessionStorage.setItem(sessionVarName, JSON.stringify(data));
roleData = data;
});
var result = Promise.resolve(roleData)
return result;
}
function checkRoleVisibility(userRoles, role) {} <-- return true or false
export {
getAllRoles ,
checkRoleVisibility
};
在NavMenu.js中
import { getAllRoles, checkRoleVisibility } from './common/Helper';
handleSubmit() {
fetch('api/User/UserAuthentification/',
....then(response => {
if (response.ok) {
this.setState(prevState => ({ userLogged: !prevState.userLogged }))
response.json().then(value => {
sessionStorage.setItem('UserLogged', true);
sessionStorage.setItem('UserLabelSession', this.state.userLabel);
sessionStorage.setItem('UserLoggedRoleId', value.userRole.roleID);
getAllRoles('NavMenu', 'UserLoggedRoles')
.then(roleData => {
this.setState({
loggedUserRoles: roleData,
loading: false
});
});
this.props.alert.success("Dobro dosli");
})
}
}
但是问题来了,就是在render()
本身中,我有一个控件navBar
调用
checkRoleVisibility(this.state.loggedUserRoles, 'SeeTabRadniNalozi')
来自帮助程序的,该函数发送this.state.loggedUserRoles
作为参数,该参数假定是从handleSubmit()
进行获取,但未定义,获取完成,将loading
设置为true,渲染完成,但没有什么都不显示
我有this.state.loading
,并据此显示控制权...
let navMenu = this.state.loading ? <div className="loaderPosition">
<Loader type="Watch" color="#1082F3" height="200" width="200" />
</div> : !this.state.userLogged ? logInControl : navBar;
如果我在控制器上设置了一个断点,我可以看到我的方法正在被getAllRoles
函数调用,但是我也可以看到该应用程序继续进行渲染,并且不等待承诺返回到的填充状态loggedUserRoles
。
问题是,为什么在将load设置为true之前,渲染既不等待我的角色获取,也不等待promise解析呢?
我检查了这个答案Wait for react-promise to resolve before render,然后将this.setState({ loading: false });
放在了componentDidMount()
上,但是加载的div显示为全时显示
答案 0 :(得分:1)
据我了解,你在打电话
this.setState(prevState => ({ userLogged: !prevState.userLogged }))
如果响应正常。这将导致React进行异步调用,以便在有时间时设置新的状态。
但是您需要来自
的资源this.setState({
loggedUserRoles: roleData,
loading: false
});
何时要将userLogged
设置为true,对吗?
因此,可能是在您将loggedUserRoles
设置为true之前,React调用已渲染。如果我对您的理解正确,那将会导致错误。
您可以像这样简单地将userLogged
状态设置为其他状态:
userLogged
编辑:
此外,您想在getAllRoles中更改Promise创建。你要回来
this.setState({
userLogged: true,
loggedUserRoles: roleData,
loading: false
});
这将直接导致空数组,因为这是var result = Promise.resolve(roleData)
return result;
的初始值。因此,您总是从该方法返回一个空数组,而不必理会所获取的结果。
您有多种解决方法。我更喜欢使用async / await的简洁易读的方式:
roleData
或者如果您想留下来承诺
:async getAllRoles(formName, sessionVarName){
var roleId = sessionStorage.getItem('UserLoggedRoleId');
const response = await fetch(...);
const data = response.json();
sessionStorage.setItem(sessionVarName, JSON.stringify(data));
return data;