初學者指南:完整解析 useMutation 的參數與用法

更新日期: 2025 年 6 月 10 日

GraphQL 是現代前端開發中非常熱門的 API 技術,而在 React 應用中,Apollo Client 是最常使用的 GraphQL 工具。

當你需要「新增 / 更新 / 刪除」資料時,useMutation 是我們的主要利器。

但除了發送請求之外,useMutation 其實還能透過「第二個參數:設定物件(options object)」做更多事,包括:

  • 傳入變數
  • 成功或失敗時要執行的 callback
  • 快取更新
  • 實作樂觀 UI
  • 設定 headers
  • 等待 refetch 完成

這篇文章將帶你完整理解 useMutation 的參數用法,從基本到進階,適合 Apollo Client 新手或希望進一步掌握 GraphQL 實務技巧的開發者。

useMutation 是什麼?

在 Apollo Client 中,useMutation 是一個專門用來發送 GraphQL mutation 請求 的 React Hook。

在 GraphQL 中,「mutation」指的是對伺服器資料的寫入操作,像是:

  • 新增文章
  • 更新使用者資訊
  • 刪除留言

useMutation 就是用來幫我們完成這些操作的工具。

為什麼用 Hook?

React 中的 Hook 是一種讓我們在函式型元件中使用 state 與副作用的機制。

Apollo Client 將 mutation 封裝成 Hook,原因有三:

  1. 符合 React 思維:使用 useMutation 可以讓資料邏輯緊貼 UI 元件。
  2. 內建狀態管理:它會自動提供 loading、error、data 等狀態值,讓你能根據請求狀況更新畫面。
  3. 整合 Apollo 快取邏輯:可以搭配 options object 操作快取、錯誤處理與 refetch 等行為。

基本語法結構

const [createPost, { data, loading, error }] = useMutation(CREATE_POST);

拆解說明如下:

  • createPost觸發函式,當你要發送 mutation 時就執行它(通常在 onClickonSubmit 中呼叫)
  • CREATE_POST:一段 GraphQL 的 mutation 語法(通常用 gql 標記寫成常數)
  • data:請求成功後的回傳資料
  • loading:布林值,表示請求是否還在進行中
  • error:如果發生錯誤,這裡會帶有錯誤資訊

範例:

const [createPost, { data, loading, error }] = useMutation(CREATE_POST);

const handleSubmit = () => {
  createPost({
    variables: {
      title: '我的第一篇文章',
      content: '這是一段測試內容'
    }
  });
};

認識第二個參數:設定物件(Options Object)

useMutation 可以接受第二個參數,也就是本文的重點 —— 「設定物件(options object)」。

這個物件用來「設定 mutation 的額外行為」,例如:

  • 要傳哪些變數(variables
  • 成功或失敗時該怎麼處理(onCompletedonError
  • 快取要怎麼更新(updaterefetchQueries
  • 要不要顯示假資料做出樂觀 UI 效果(optimisticResponse
  • 要不要傳自訂 header(context

實際語法範例

const [createPost] = useMutation(CREATE_POST, {
  variables: {
    title: 'Hello World',
    content: '這是一篇文章'
  },
  onCompleted(data) {
    console.log('新增成功!', data);
  },
  onError(error) {
    console.error('新增失敗:', error.message);
  }
});

這段程式碼等同於:

  • 幫你送出 GraphQL mutation 請求
  • 傳入 mutation 所需的參數
  • 成功時印出回傳結果
  • 失敗時顯示錯誤訊息

注意事項

這個設定物件(第二個參數)只能寫 Apollo Client 預定義的 key,像是:

  • variables
  • onCompleted
  • onError
  • refetchQueries
  • update
  • context
  • optimisticResponse
  • awaitRefetchQueries

如果你寫了像這樣的 key:

useMutation(CREATE_POST, {
  foo: 'bar'  // ❌ 錯誤!Apollo 不認得這個設定
});
  • JavaScript 會忽略它
  • TypeScript 會直接報錯(這也是 TypeScript 的好處)

常用參數介紹

Apollo Client 的 useMutation 支援多種參數,讓你可以更靈活控制整個請求的行為,包括資料傳入、成功與錯誤的後續處理、快取更新等。

以下為常見設定項目,將搭配背景說明與範例幫助你理解每個參數的實際用法。

variables:傳入 GraphQL 所需的變數

用途:提供給 mutation 執行所需的參數,對應你在 GraphQL 文件中定義的 $變數名稱

背景說明:GraphQL mutation 支援變數機制,能讓請求更彈性、更容易重複使用,並避免硬編碼。Apollo 建議將變數透過 variables 屬性傳入,而非直接寫死在 gql 語法中。

範例

const [createPost] = useMutation(CREATE_POST, {
  variables: {
    title: '我的第一篇文章',
    content: '內容內容內容'
  }
});

提示

  • variables 的 key 必須對應到你 GraphQL 中定義的變數名稱。
  • 如果變數是可選的(例如 $subtitle: String),你可以選擇不傳。

onCompleted:成功時的 callback

用途:當 mutation 成功執行、收到伺服器回傳資料後,自動觸發此函式。

常見情境

  • 顯示成功訊息(如 toast)
  • 導頁至其他畫面(如跳回列表)
  • 清空表單

範例

const [createPost] = useMutation(CREATE_POST, {
  onCompleted(data) {
    alert(`成功新增文章:${data.createPost.title}`);
  }
});

提示

  • 回傳值會透過 data 傳入函式中,你可以自由使用裡面的資料。
  • 若 mutation 沒有回傳任何欄位,data 會是 undefined

onError:錯誤時的 callback

用途:當 mutation 發生錯誤(例如伺服器錯誤、驗證失敗、網路錯誤等),會觸發這個函式。

常見用途

  • 顯示錯誤訊息
  • 將錯誤記錄下來(例如送至錯誤追蹤服務)
  • 高亮表單錯誤欄位

範例

const [createPost] = useMutation(CREATE_POST, {
  onError(error) {
    console.error('新增失敗:', error.message);
  }
});

提示

  • error 物件是 Apollo Client 的 GraphQL error 實例,可透過 .message.graphQLErrors.networkError 存取詳細錯誤原因。
  • 可搭配 errorPolicy 調整錯誤處理邏輯(預設為 “none”)。

refetchQueries:成功後重新查詢特定 Query

用途:當 mutation 執行成功後,重新發送一個或多個 Query 來同步更新畫面資料。

背景說明:某些情況下,手動更新快取太麻煩或難以維護,可以直接透過這個選項自動重新查詢。

範例

const [createPost] = useMutation(CREATE_POST, {
  refetchQueries: [{ query: GET_POSTS }]
});

提示

  • 支援多個查詢(以陣列表示)。
  • 也可加上變數:{ query: GET_POSTS, variables: { category: 'news' } }
  • 預設不會等 refetch 完成就結束 mutation(需搭配 awaitRefetchQueries)。

⚠️ 缺點:會額外發出網路請求,對效能有些影響。

update:手動操作 Apollo 快取

用途:當 mutation 成功後,你可以直接操作 Apollo 的快取內容,讓畫面同步更新而不必重新查詢。

背景說明:這是控制效能與自訂畫面更新的進階功能。

範例

const [createPost] = useMutation(CREATE_POST, {
  update(cache, { data }) {
    const newPost = data.createPost;
    const existing = cache.readQuery({ query: GET_POSTS });

    cache.writeQuery({
      query: GET_POSTS,
      data: {
        posts: [newPost, ...existing.posts]
      }
    });
  }
});

提示

  • cache.readQuerycache.writeQuery 是操作快取的基本方式。
  • 快取資料結構必須和 query 對應完全一致。
  • 若 mutation 回傳資料太少,這邊可能無法更新完整快取。

optimisticResponse:先顯示預期結果,打造樂觀 UI

用途:在伺服器還沒真正回應之前,預先在畫面上顯示「假資料」,達到 UI 即時回應的效果。

常見情境

  • 點讚按鈕馬上加一
  • 新增留言立即顯示
  • 刪除項目立即從列表消失

範例

const [createComment] = useMutation(CREATE_COMMENT, {
  optimisticResponse: {
    createComment: {
      id: 'temp-id',
      content: '我先顯示了',
      __typename: 'Comment'
    }
  }
});

提示

  • __typename 是必需的,否則 Apollo Cache 可能無法辨識這筆資料。
  • 這筆「假資料」會在真正回應後被替換,若失敗則會自動復原。

context:傳遞額外資訊(如認證 Header)

用途:給中介層(如 Apollo Link、middleware)傳遞額外資訊,例如認證用的 token。

範例

const [deletePost] = useMutation(DELETE_POST, {
  context: {
    headers: {
      authorization: `Bearer ${token}`
    }
  }
});

提示

  • 此 context 僅作用於這次的 mutation 請求。
  • 若你已經在 Apollo Client 的 setContext 裡統一處理授權,一般不需要每次手動設。

awaitRefetchQueries:等待 refetch 查詢完成後再結束 mutation

用途:讓 mutation 等待 refetchQueries 完成後才結束流程,適用於需要在 refetch 後再做後續操作的場景。

範例

const [createPost] = useMutation(CREATE_POST, {
  refetchQueries: [{ query: GET_POSTS }],
  awaitRefetchQueries: true
});

提示

  • 這會讓 mutation 的 Promise 等 refetch 完成後才 resolve。
  • 適合用於有「下一步」依賴 refetch 結果的流程,例如頁面跳轉、顯示 loading spinner 等。

以上就是 useMutation 中最常見的設定項目介紹。

每個參數都有它的使用情境與搭配時機,建議初學者可以先熟悉基本參數如 variablesonCompletedonError,再逐步學習 updateoptimisticResponse 等進階功能。

結語

useMutation 的第二個參數(設定物件)是 GraphQL 請求中非常強大的一環。熟悉它能幫你:

  • 提升使用者體驗
  • 優化效能與快取邏輯
  • 管理請求流程與錯誤處理

當你學會善用這些參數,你的 GraphQL 實作將更靈活、穩定、好維護。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *