簡體   English   中英

反應:在 useEffect 掛鈎中的網絡請求后更新然后訪問 state。 State 仍然過時

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM