iT邦幫忙

2025 iThome 鐵人賽

DAY 16
0
Modern Web

30天入門:學會第一個前端框架-React系列 第 16

Day 16 | React入門:useEffect 應用-資料載入與錯誤處理

  • 分享至 

  • xImage
  •  

載入資料 ( Loading ) 和錯誤檢查 (Error) 的用意

  • 使用 API 抓資料時,資料會有一個讀取的動作,因此需要一個載入狀態,讓使用者知道資料還在讀取
  • API 請求有可能失敗(像是網路問題、伺服器錯誤等),因此需要錯誤處理,顯示提示訊息

解法:在useEffect加入流程的控制

  1. 組件渲染時 → useEffect 觸發 API 請求
  2. 載入中 → setIsLoading(true)
  3. 成功拿到資料 → setBlogs(data),同時 setIsLoading(false)
  4. 如果錯誤 → setError(err.message),同時 setIsLoading(false)

範例:

Home.js

import { useEffect, useState } from "react";
import BlogList from "./BlogList";

const Home = () => {
  const [blogs, setBlogs] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(false);

  useEffect(() => {
    setTimeout(() => {
      fetch("http://localhost:8000/blogs")
      .then(res => {
        if (!res.ok) { 
          throw Error("無法讀取資料來源");
        }
        return res.json();
      })
      .then(data => {
        setIsLoading(false);
        setBlogs(data);
        setError(null);
      })
      .catch(err => {
        setIsLoading(false);
        setError(err.message);
      })
    }, 100);
  }, [])

  return (
    <div className="home">
      {error && <div>{ error }</div>}
      { isLoading && <div>資料載入中...</div> }
      {blogs && <BlogList blogs={blogs} />}
    </div>
  );
}
 
export default Home;

Loading

const [isLoading, setIsLoading] = useState(true);
表示「資料是否還在載入中」

  • 一開始設為 true,代表一進到頁面就正在等待 API 回應
  • 當資料載入完成(或失敗)時,會改成 false
.then(data => {
        setIsLoading(false);
        setBlogs(data);
        setError(null);
 })

setIsLoading(false);

  • 拿到資料,載入狀態結束

setBlogs(data);

  • 把 API 拿到的資料存進 blogs state,讓 React 可以重新渲染畫面

setError(null);

  • 代表這次沒有發生錯誤,把錯誤狀態清空

return
{ isLoading && <div>資料載入中...</div> }

  • 在畫面上顯示「資料載入中...」,直到拿到資料

註:setTimeout(() =>{{(…)}, 100) 主要是延長資料讀取的時間,方便使用者知道目前狀態

瀏覽器執行畫面
https://i.meee.com.tw/AelUCuR.gif


Error

const [error, setError] = useState(null);
用來存放錯誤訊息

  • 一開始是 null,代表沒有錯誤

setError(err.message);

  • 把錯誤訊息存進 error 這個狀態

檢查流程

if (!res.ok) { throw Error("無法讀取資料來源") }

  • 檢查伺服器回應是否成功,如果不成功就丟出錯誤,由 .catch 接收

註:res.ok是 Response 物件內建的屬性,幫忙檢查狀態碼是不是 200–299 之間

.catch(err => {
        setIsLoading(false);
        setError(err.message);
        }) 

.catch(err => {...})

  • 如果 fetch 過程中出現問題,像是:網路斷線、沒連結到伺服器,就會跳到 .catch,把錯誤物件傳進來

setIsLoading(false);

  • 代表載入結束,把 loading 狀態關掉,讓 UI 從讀取中變回正常狀態

setError(err.message);

  • 把錯誤物件 err 裡的錯誤訊息 (message) 存到 error state,這樣 UI 就能根據 error 來顯示錯誤提示

return
{ error && <div>{ error }</div> }

  • 如果有錯誤,就會顯示錯誤訊息

瀏覽器執行畫面
https://i.meee.com.tw/QmiecBf.gif


上一篇
Day 15 | React入門:useEffect 結合 JSON Server用法
下一篇
Day 17 | React入門:Custom Hook (自定義Hook)
系列文
30天入門:學會第一個前端框架-React17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言