React - 在渲染之前等待承诺
React - wait for promise before render
我想不通,如果你能给我指出正确的方向。在我的 NavMenu.js 上,我有登录(两个输入和一个提交按钮,我在上面调用 handleSubmit()
在 handleSubmit()
中,我正在检查用户登录凭据,效果很好,但在我确认登录后,我继续执行下一次提取以检查用户角色(和 returning 承诺)和可见性在申请中
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')
from helper,它发送this.state.loggedUserRoles
作为参数,它应该被填充到fetch from handleSubmit()
但是它是未定义的,fetch finish,设置loading
on 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
函数调用,而且我还可以看到应用程序继续渲染并且不等待 [=51] 的承诺=] 填充 loggedUserRoles
.
的状态
所以问题是,为什么渲染不等待我的角色获取,也不等待 promise 解决后再将加载设置为 true?
我检查了这个答案 Wait for react-promise to resolve before render 并将 this.setState({ loading: false });
放在 componentDidMount()
上,但随后加载 div 显示完整
据我所见和理解,你正在打电话
this.setState(prevState => ({ userLogged: !prevState.userLogged }))
如果反应没问题。这将导致来自 React 的异步调用,以便在有时间时设置新状态。
但是你需要来自
的资源
this.setState({
loggedUserRoles: roleData,
loading: false
});
每当您想将 userLogged
设置为 true 时,对吗?
因此,React 可能会在您设置 loggedUserRoles
之前但在 userLogged
设置为 true 之后调用渲染。如果我理解正确,那会导致错误。
您可以像这样简单地将 userLogged
状态与其他状态一起设置:
this.setState({
userLogged: true,
loggedUserRoles: roleData,
loading: false
});
编辑:
此外,您想更改 getAllRoles 中的 Promise 创建。你回来了
var result = Promise.resolve(roleData)
return result;
这将直接导致空数组,因为这是 roleData
的初始值。因此,您总是从该方法返回一个空数组,而不必担心获取的结果。
您有多种方法可以解决这个问题。我更喜欢使用 async/await:
的简洁易读的方式
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;
或者如果您想继续使用 Promise:
function getAllRoles(formName, sessionVarName){
return new Promise((resolve, reject) => {
var roleId = sessionStorage.getItem('UserLoggedRoleId');
fetch(...)
.then(roleResponse => roleResponse.json())
.then(data => {
sessionStorage.setItem(sessionVarName, JSON.stringify(data));
resolve(data);
});
我想不通,如果你能给我指出正确的方向。在我的 NavMenu.js 上,我有登录(两个输入和一个提交按钮,我在上面调用 handleSubmit()
在 handleSubmit()
中,我正在检查用户登录凭据,效果很好,但在我确认登录后,我继续执行下一次提取以检查用户角色(和 returning 承诺)和可见性在申请中
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')
from helper,它发送this.state.loggedUserRoles
作为参数,它应该被填充到fetch from handleSubmit()
但是它是未定义的,fetch finish,设置loading
on 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
函数调用,而且我还可以看到应用程序继续渲染并且不等待 [=51] 的承诺=] 填充 loggedUserRoles
.
所以问题是,为什么渲染不等待我的角色获取,也不等待 promise 解决后再将加载设置为 true?
我检查了这个答案 Wait for react-promise to resolve before render 并将 this.setState({ loading: false });
放在 componentDidMount()
上,但随后加载 div 显示完整
据我所见和理解,你正在打电话
this.setState(prevState => ({ userLogged: !prevState.userLogged }))
如果反应没问题。这将导致来自 React 的异步调用,以便在有时间时设置新状态。
但是你需要来自
的资源this.setState({
loggedUserRoles: roleData,
loading: false
});
每当您想将 userLogged
设置为 true 时,对吗?
因此,React 可能会在您设置 loggedUserRoles
之前但在 userLogged
设置为 true 之后调用渲染。如果我理解正确,那会导致错误。
您可以像这样简单地将 userLogged
状态与其他状态一起设置:
this.setState({
userLogged: true,
loggedUserRoles: roleData,
loading: false
});
编辑:
此外,您想更改 getAllRoles 中的 Promise 创建。你回来了
var result = Promise.resolve(roleData)
return result;
这将直接导致空数组,因为这是 roleData
的初始值。因此,您总是从该方法返回一个空数组,而不必担心获取的结果。
您有多种方法可以解决这个问题。我更喜欢使用 async/await:
的简洁易读的方式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;
或者如果您想继续使用 Promise:
function getAllRoles(formName, sessionVarName){
return new Promise((resolve, reject) => {
var roleId = sessionStorage.getItem('UserLoggedRoleId');
fetch(...)
.then(roleResponse => roleResponse.json())
.then(data => {
sessionStorage.setItem(sessionVarName, JSON.stringify(data));
resolve(data);
});