setState 不会在初始提交时更新状态,仅在后续提交时更新状态



我正在尝试使用会话存储来设置一些数据,它第一次不起作用,但第二次有效。

const login = async (email, password) => {
try {
const user = await loginUser({
variables: {
email,
password
}
});
const { userId, token, expiresIn } = user.data.loginUser;
setUserData({
token: token,
userId: userId,
expiresIn: expiresIn
})
sessionStorage.setItem('interdevs-data', JSON.stringify({ 
"token": userData.token, 
"userId": userData.userId, 
"expiresIn": userData.expiresIn 
}));
} catch(err) {
setLoginErr(err);
};
};

我希望它在初始提交时设置状态,但是当我再次单击提交时可以设置它

setUserData()方法是异步的,这意味着在它自己的逻辑完成之前,没有什么可以阻止在它之后编写的代码执行。这适用于所有状态更新方法。

可能发生的情况是,sessionStorage.setItem()块在您完全更新上一个块中的状态之前运行。因此,第一次在本地存储中没有什么可以保存的。但在后续尝试中,状态将使用上次更新中的令牌/用户信息进行更新。

有几种方法可以解决此问题:

1( 只是使用您创建的变量更新本地存储,而不是等待状态完成:

const login = async (email, password) => {
try {
const user = await loginUser({
variables: {
email,
password
}
});
const { userId, token, expiresIn } = user.data.loginUser;
setUserData({
token: token,
userId: userId,
expiresIn: expiresIn
})
sessionStorage.setItem('interdevs-data', JSON.stringify({ 
"token": token, 
"userId": userId, 
"expiresIn": expiresIn 
}));
} catch(err) {
setLoginErr(err);
};
};

2( 使用useEffect()在状态更改时更新本地存储。

useEffect(() => {
sessionStorage.setItem('interdevs-data', JSON.stringify({ 
"token": userData.token, 
"userId": userData.userId, 
"expiresIn": userData.expiresIn 
}));
}, [user]) //swap user with whatever you called your state
const login = async (email, password) => {
try {
const user = await loginUser({
variables: {
email,
password
}
});
const { userId, token, expiresIn } = user.data.loginUser;
setUserData({
token: token,
userId: userId,
expiresIn: expiresIn
})
} catch(err) {
setLoginErr(err);
};
};

React Hook中的useStateasynchronousReact Component中的this.setState

因此,您可以尝试:

const login = async (email, password) => {
try {
const user = await loginUser({
variables: {
email,
password
}
});
const { userId, token, expiresIn } = user.data.loginUser;
// setUserData({
//   token: token,
//   userId: userId,
//   expiresIn: expiresIn
// })
// userData here not yet updated
sessionStorage.setItem('interdevs-data', JSON.stringify({ 
"token": token, 
"userId": userId, 
"expiresIn": expiresIn 
}));
// In your case, you can direct access to user.data.loginUser. Don't need use setUserData
} catch(err) {
setLoginErr(err);
};
};

或者,如果您仍然想使用setUserData,请尝试应用如下useEffect

const login = async (email, password) => {
try {
const user = await loginUser({
variables: {
email,
password
}
});
const { userId, token, expiresIn } = user.data.loginUser;
setUserData({
token: token,
userId: userId,
expiresIn: expiresIn
})
} catch(err) {
setLoginErr(err);
};
};
useEffect(() => {
sessionStorage.setItem('interdevs-data', JSON.stringify({ 
"token": userData.token, 
"userId": userData.userId, 
"expiresIn": userData.expiresIn 
}));
}, [userData])

相关内容

  • 没有找到相关文章

最新更新