[英]React : Updating and then accessing state after a network request in useEffect hook. State remains stale
我试图更新和引用我的组件的初始化 function 内部的hasError
state 字段,以控制在成功初始化后是否发生重定向或是否显示错误。
这是该问题的精简版:
const [hasError, setHasError] = useState(false);
useEffect(() => {
initialize();
}, []);
async function initialize(){
try {
await networkRequest();
} catch (err) {
setHasError(true);
}
console.log(hasError); // <- is still false
if(!hasError){
redirect() // <- causes redirect even with error
}
}
function networkRequest() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject();
}, 1000);
});
}
初始化 function 应该只在组件安装时调用一次,这就是我将[]
传递给useEffect
的原因。 将[hasError]
传递给useEffect
也没有意义,因为我不希望每次hasError
更新时都运行初始化。
我见过人们推荐使用useReducer
但这似乎很棘手,因为我已经在这个组件上使用了 Redux ,然后我需要使用 2 个不同的dispatch
实例。
通常如何处理这样的用例?
您将不得不创建另一个useEffect
钩子来“监听”对hasError
的更改。 在这种情况下, setHasError
是异步的,因此新值不会立即提供给您。
我不知道你的组件的 rest 是什么样子的,但听起来你应该有某种isLoading
state 用于显示loading
消息,然后一旦你的请求完成并且失败,你就会呈现你需要的东西,或者如果它成功,你redirect
。
这是一个例子:
function App() {
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
useEffect(() => {
(async () => {
try {
await networkRequest();
isLoading(false);
} catch (error) {
setHasError(error);
isLoading(false);
}
})()
}, [])
useEffect(() => {
if (!isLoading && !hasError) {
redirect();
}
}, [isLoading, hasError]);
if (isLoading) { return "Loading"; }
// else, do whatever you need to do here
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.