iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Modern Web

現在就學React.js 系列 第 26

打造自己的 Hook:Custom Hook Day26

  • 分享至 

  • xImage
  •  

在 React 開發中,有時一些邏輯和功能會常常重複出現,若開發時沒有將程式碼做共用的話,就會到處都寫差不多像的內容,之後要做更改的話,就要同步作調整。這樣的寫法有很大的改善空間。

這時可以透過自訂 Hook,將重複的邏輯封裝成通用的程式碼片段,以便在不同元件中共用,從而提高程式碼的可讀性與維護性。

在撰寫自訂 Hook 之前,我們需要了解 React 對 Hook 命名的規範:

  • 自訂 Hook 名稱必須以 use 開頭,後面接著大寫字母,例如 useStateuseEffect。這樣的命名方式不僅有助於辨識哪些是 Hook,也能讓 React 正確處理 Hook 的規則。

Custom Hook帶來的好處:

在開發過程中,遇到需要多次重複執行的邏輯,例如 API 資料請求、表單狀態管理、或是特定的事件監聽。使用 Custom Hook 可以幫助我們:

  1. 封裝複雜邏輯:將程式碼重複的部分封裝到一個 Hook 中,避免不必要的重複程式碼。
  2. 提高可讀性與可維護性:使用自訂 Hook 可以使元件中的邏輯更加清晰、結構化。
  3. 方便跨元件共享邏輯:當多個元件需要相似的功能時,只需導入自訂 Hook,即可輕鬆共用。

接下來,我們來實作如何封裝一個 API 請求的邏輯,並做到自訂 Hook 中吧!

實作第一個 Custom Hook:useFetch

常在元件中撰寫 API 資料請求的邏輯,像是透過 axios 發送 GET 請求來獲取資料。

當這樣的邏輯重複出現時,我們可以將其封裝成自訂 Hook,讓程式碼更加簡潔且可重用。

來把 Day20 實作的 axios 請求的程式碼做個封裝處理吧!

創建 useFetch Hook

以下是一個簡單的 useFetch Hook,它可以用來處理資料請求的邏輯:


import { useState, useEffect } from 'react';
import axios from 'axios';

function useFetch(url) {
  const [data, setData] = useState([]);     // 用來存放請求回來的資料
  const [loading, setLoading] = useState(true); // 追蹤資料是否正在載入
  const [error, setError] = useState(null); // 儲存錯誤訊息

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(url);
        setData(response.data); // 資料請求成功,存入 data 狀態
        setLoading(false);      // 加載狀態設定為 false
      } catch (err) {
        setError(err.message);  // 捕捉錯誤訊息
        setLoading(false);      // 加載狀態設定為 false
      }
    };

    fetchData();  // 呼叫 fetchData 發送請求
  }, [url]); // 當 url 變更時,重新執行 useEffect

  return { data, loading, error }; // 返回狀態與資料
}

export default useFetch;

useFetch 的運作

  1. 狀態管理
    • data:儲存 API 回傳的資料。
    • loading:表示資料是否正在載入中。
    • error:若請求失敗,則儲存錯誤訊息。
  2. 資料請求
    url 變更或元件初次渲染時,useEffect 會觸發 fetchData 函數發送 HTTP 請求,並更新 dataloadingerror 狀態。
  3. 錯誤處理
    若請求失敗,error 狀態將儲存錯誤訊息,並顯示相應的錯誤內容。

使用 useFetch Hook

在需要進行資料請求的任何元件中使用 useFetch 來取得資料,從而簡化程式碼結構。


import React from 'react';
import useFetch from './useFetch'; // 引入自訂的 useFetch Hook

function PostList() {
  const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts');

  if (loading) return <p>Loading...</p>; // 當資料尚未載入時顯示 Loading
  if (error) return <p>Error: {error}</p>; // 顯示錯誤訊息

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li> // 渲染每個貼文標題
      ))}
    </ul>
  );
}

export default PostList;

程式碼解析

  • 加載狀態 (loading):當資料尚未完成載入時,顯示「Loading...」。一旦載入完成後,loading 狀態設為 false
  • 錯誤狀態 (error):若請求出現錯誤,則顯示錯誤訊息。
  • 資料顯示:若成功獲取資料,則透過 .map 方法遍歷 data 陣列,並渲染每個貼文的標題。

總結

Custom Hook 是 React 中一個強大且靈活的工具,能夠幫助我們將相似的邏輯封裝成可重用的模組。透過自訂 Hook,可以大大減少重複的程式碼,使元件變得更簡潔、易於維護。

在這篇文章中練習創建 useFetch 這個自訂 Hook,封裝了 API 請求邏輯,在往後需要用到

Get 請求時,可以直接用useFetch做處理,是相當快速和方便的。

我們可以依據開發專案的需求,去設計和客製化自己需要用到的 Custom Hook ,像是表單驗證、動畫、登入驗證等其他邏輯。

參考資料:

後記

本文將會同步更新到我的部落格

黃禎平 – Medium


上一篇
useCallback的使用時機 - Day25
下一篇
React useReducer 進階狀態管理 -Day27
系列文
現在就學React.js 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言