主體
分支
主體 (6.23.1)開發
版本
6.23.1v4/5.xv3.x
useResolvedPath

useResolvedPath

類型宣告
declare function useResolvedPath(
  to: To,
  options?: { relative?: RelativeRoutingType }
): Path;

這個 hook 會將提供的 to 值中的所在位置之 pathname 解析成目前所在位置的 pathname

在從相對路徑建立連結時這個功能會很有用。例如,查看 <NavLink> 的原始程式碼,其中會內部呼叫 useResolvedPath 來解析連結的頁面的完整 pathname

有關更多資訊,請見 resolvePath

Splat 路徑

useResolvedPath 對於 splat 路徑的原始邏輯運行方式不同,而這事後回看是個不正確、有 bug 的行為。這已在 6.19.0 中修復,但已判斷出許多現有的應用程式 依賴此行為,所以此修正已在 6.20.1 還原,並在 6.21.0 中在 future.v7_relativeSplatPath 未來旗標下重新引入。此行為在 React Router v7 中會成為預設行為,因此建議您方便時更新應用程式,以便做好升級到 v7 的準備。

請注意,這是 React Router 中所有相對路由的基礎,因此這也適用於以下相對路徑程式碼流

  • <Link to>
  • useNavigate()
  • useHref()
  • <Form action>
  • useSubmit()
  • 從 loader 和動作傳回的相關路徑 redirect 回應

沒有標記的行為

若未啟用此標記,預設行為會在 星形號路徑 (*) 中解析相對路徑時忽略路徑的星形號部分。因此,假設路由樹為

<BrowserRouter>
  <Routes>
    <Route path="/dashboard/*" element={<Dashboard />} />
  </Routes>
</BrowserRouter>

若您目前位於網址 /dashboard/teamsDashboard 組件中的 `useResolvedPath("projects")` 會轉譯為 /dashboard/projects,因為我們所相對的「目前」位置會被視為 /dashboard但不包含「teams」星形號的值

這使得在「同層」星形號路由 (/dashboard/teams/dashboard/projects 等) 之間進行路由時稍微方便一些,但會造成其他不一致,例如

  • useResolvedPath(".") 不會再轉譯為該路由的目前位置,它實際上會從 /dashboard/teams 將您「向上」轉譯為 /dashboard
  • 若您將路由定義變更為使用動態參數 (<Route path="/dashboard/:widget">),則 Dashboard 組件中的所有轉譯路徑都會中斷,因為動態參數值不會像星形號值那樣被忽略

將星形號路由定義為子路由後,狀況會更糟

<BrowserRouter>
  <Routes>
    <Route path="/dashboard">
      <Route path="*" element={<Dashboard />} />
    </Route>
  </Routes>
</BrowserRouter>
  • 現在,<Dashboard /> 中的 useResolvedPath(".")useResolvedPath("..") 會轉譯為完全相同的路徑
  • 若您使用資料路由並在星形號路由上定義 動作,則 <Dashboard> 中的 <Form> 提交會產生 405 錯誤,因為它們 (預設) 會提交到 ".",而這個路徑會轉譯為父路由 /dashboard,但它沒有 動作

有標記的行為

啟用標記後,這個「錯誤」就已修復,因此各種路由類型的路徑轉譯都是一致的,而且 useResolvedPath(".") 會永遠轉譯為與情境路由相同的目前路徑名稱。這包括任何動態參數或星形號參數的值。

若您想要在星形號路由內的「同層」路由之間導航,建議您將星形號路由移動到它自己的子路由,並使用相對於父路由的路徑 useResolvedPath("../teams")useResolvedPath("../projects") 來導航至同層的 /dashboard 路由。請注意,我們在這裡也使用 index,以便也能透過網址 /dashboard 來呈現 <Dashboard> 組件。

<BrowserRouter>
  <Routes>
    <Route path="/dashboard">
      <Route index path="*" element={<Dashboard />} />
    </Route>
  </Routes>
</BrowserRouter>