[英]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.