iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
佛心分享-SideProject30

用 Next.js 實作屋況查詢評估專家網站系列 第 27

[Day 27] 撰寫 Apollo Custom Hook

  • 分享至 

  • xImage
  •  

大綱

  • LazyQueryResultTuple 是甚麼?
  • 為 API 建立 Input 跟 Output 類型
  • useLazyQuery 的理解

1. LazyQueryResultTuple 是甚麼?

LazyQueryResultTuple 是 Apollo Client 提供的一個類型,用來定義使用 useLazyQuery 回傳的結果。當我們使用 useLazyQuery 來做惰性查詢時,它會回傳一個 tuple(元組),包含兩個主要部分:

  • Function: 第一個元素是用來觸發查詢的函數。例如,在我們的情境中,可以透過按鈕或其他事件來觸發這個函數。
  • Object: 第二個元素是一個物件,包含查詢結果的相關資訊,例如 data、loading、error 等。
    這個類型可以幫助我們明確地知道使用 useLazyQuery 之後回傳的內容,這樣在使用時就可以享有 TypeScript 提供的自動完成和類型檢查功能。

2. 為 API 建立 Input 跟 Output 類型

在進行 GraphQL API 查詢時,由於有使用到TypeScript,通常會為 API 的 Input (API 輸入) 和 Output (API 輸出) 定義類型。我們建立了兩個 interface 分別是 Data 和 Variables:

Data : 定義了查詢結果的類型。在這裡,它表示 questions 是一個 Question 物件的陣列。每個 Question 物件包含 id、question、answer 等屬性。

interface Data {
  questions: Question[];
}

Variables : 定義了查詢所需的變數。在這個範例中,變數是 keyword,用來搜尋特定問題。

interface Variables {
  keyword: string;
}

這些類型定義不僅使程式碼更易於理解,還能讓編譯器在編寫代碼時提供更多自動完成的提示,幫助我們避免一些潛在的錯誤。

3. useLazyQuery 的理解

useLazyQuery 是 Apollo Client 提供的一個 hook,允許我們進行惰性查詢(Lazy Query)。與 useQuery 不同的是,useQuery 會在組件掛載(mount)時立即執行查詢,而 useLazyQuery 則是等到明確觸發時才執行。

這種特性非常適合在某些情境下的應用,例如用戶必須點擊按鈕或進行特定操作後才進行查詢的情況。這樣的設計不僅提高了性能(因為不會不必要地執行查詢),也可以讓我們在需要時再去請求資料。

在我們的範例中,useQueryQuestions 是一個自訂的 hook,它使用了 useLazyQuery 來實現查詢功能:

export default function useQueryQuestions(
  options?: Options
): LazyQueryResultTuple<Data, Variables> {
  const [query, { data, ...result }] = useLazyQuery<Data, Variables>(
    QUERY,
    options
  );
  return [query, { data: data, ...result }];
}

這段代碼表示 useQueryQuestions 回傳一個包含兩個元素的 tuple:一個是觸發查詢的函數 query,另一個是包含查詢結果的物件 { data, ...result }

完整程式碼片段:

import {
  type QueryResult,
  gql,
  useQuery,
  useLazyQuery,
  LazyQueryResultTuple,
} from "@apollo/client";
import type { QueryOptions } from "../type";
interface Question {
  answer: string;
  id: string;
  question: string;
}
const QUERY = gql`
  query Questions($keyword: String!) {
    questions(keyword: $keyword) {
      answer
      id
      question
    }
  }
`;

interface Data {
  questions: Question[];
}

interface Variables {
  keyword: string;
}

type Options = QueryOptions<Data, Variables>;

/** -   */
export default function useQueryQuestions(
  options?: Options
): LazyQueryResultTuple<Data, Variables> {
  const [query, { data, ...result }] = useLazyQuery<Data, Variables>(
    QUERY,
    options
  );
  return [query, { data: data, ...result }];
}


上一篇
[Day 26] 對寫好的API進行測試
下一篇
[Day 28] 記錄技術細節-在使用Apollo前為整個<App /> 註冊吧
系列文
用 Next.js 實作屋況查詢評估專家網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言