React(以及現代網頁開發)的語境中,SPA 指的是 Single Page Application(單頁應用程式)

什麼是 SPA?

傳統的網站(Multi-Page Application, MPA)在你點擊連結、切換頁面時,瀏覽器會向伺服器重新請求一個全新的 HTML 檔案,畫面會整個閃一下、重新載入。

而 React 打造的 SPA 正好相反:

  • 只有一個 HTML 檔案: 瀏覽器只在第一次進入網站時,下載一個基本上是空白的 index.html 和一大包 JavaScript(React 程式碼)。
  • 前端路由(Client-side Routing): 當你在網站內切換頁面(例如從首頁到設定頁)時,瀏覽器並不會向伺服器重新請求新網頁。React Router 等套件會攔截點擊事件,直接在前端用 JavaScript 把舊的組件(Component)拔掉,換上新的組件。
  • 體驗流暢: 因為不需要重新整理網頁,頁面切換就像桌面軟體或 App 一樣秒開、極度流暢。

解讀你遇到的問題

你提到的這句話非常精準地點出了 SPA 的特性:

“The refetchOnWindowFocus doesn’t fire when navigating within the same SPA.”

如果你使用的是 TanStack Query (React Query) 或類似的 Data Fetching 套件,refetchOnWindowFocus 的觸發條件是「瀏覽器視窗重新獲得焦點」(例如:你切換到別的視窗看 LINE,再切回瀏覽器;或者切換分頁再切回來)。

因為在同一個 SPA 裡面切換頁面(Navigating):

  1. 視窗從頭到尾都沒有失去焦點,瀏覽器只是在執行 React 的組件切換。
  2. 對瀏覽器來說,使用者根本沒有「離開視窗再回來」。
  3. 因此,refetchOnWindowFocus 絕對不會因為你在 SPA 內轉址而觸發。

你的解決方案完全正確

“The real fix is: invalidate getMe and all suggestion logs from AccessRolesPage after removing the reviewer delegate”

這正是處理 SPA 狀態同步的標準標準做法(Best Practice):

在 SPA 中,因為頁面不會重新載入,舊頁面的快取數據可能還留在記憶體中。當你執行了某個動作(例如:移除審查員代理人 reviewer delegate),後端的資料已經變了,但前端畫面可能還看得到舊資料。

透過主動呼叫 queryClient.invalidateQueries

  • 你明確告訴 React Query:「getMesuggestion logs 這幾筆資料已經過期(stale)了!」
  • React Query 就會立刻在背景重新向 API 發送請求(Refetch),確保使用者切換到 AccessRolesPage 時,看到的是最新的正確資料。

這種「動作完成後,主動使相關快取失效」的機制,是維持 SPA 資料同步最乾淨、最不通靈的解法!

發佈留言

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