React useEffect 執行順序

參加了六角學院的鐵人競賽,期望自己每週都能寫一篇技術文章,先從工作上遇到的問題與解決方案開始切入。

React useEffect 在同一 component 的執行順序

  useEffect(() => {
    console.log("1");
    const fetchData = async () => {
      try {
        const result1 = await axios.get(url) 
        console.log(result1)
      } catch (error) {
        // error handle
      }
    };
    fetchData();
  }, []);

  useEffect(() => {
    console.log("2");
    const fetchData = async () => {
      try {
        const result2 = await axios.get(url) 
        console.log(result2)
      } catch (error) {
        // error handle
      }
    };
    fetchData();
  }, []);

  useEffect(() => {
    console.log("3");
    const fetchData = async () => {
      try {
        const result3 = await axios.get(url) 
        console.log(result3)
      } catch (error) {
        // error handle
      }
    };
    fetchData();
  }, []);

  console.log("4")

如果我執行以上程式 log 出的順序應該是什麼呢?答案是:

4
1
2
3
result1 or result2 or result3 // 取決於 api response 的順序
4

對於我來說滿驚訝的發現是 4 會先被 log 出來,代表 component 會先被檢查過一次有哪些 useEffect hook 再來依序執行。useEffect 的確會依序執行卻不會被 hook 裡面的 api fetch 卡住,如果回傳值還沒回來就會先執行 接下來一個 useEffect,值到 任何一個 api response 回傳,不一定是最先執行的 useEffect 會先回傳 response。

如果要確定收到 3 個不同的 api response 再 return 畫面應該怎麼做呢?使用 Promise.all :

  useEffect(() => {
    const fetchData = async () => {
      try {
        const [result1, result2, result3] = await Promise.all([
          axios.get(url),
          axios.get(url),
          axios.get(url)
        ]);
      } catch (error) {
        // error handle
      }
    };
    fetchData();
  }, []);

收到 result1, result2, result3 三個 response 才會繼續執行 try 裡面的下一行,另外 try api fetch 產生的 catch error 是指非 state 200 response,通常是 404 ,如果 api 自己要 log 出 error message 需要另外寫 if (result.state == “ok”) else if (result.state == “error”) 等邏輯。

Post images
依照慣例放張梗圖
Share on facebook
Facebook
Share on linkedin
LinkedIn
Share on twitter
Twitter

More to explorer

Close Menu