react-router
)@react-router/*
)本頁面列出 React Router 自 v6.0.0
以來的所有版本/版本說明。對於 v6 之前的版本,請參考 Github 版本頁面。
我們在此檔案中管理版本說明,而不是分頁的 Github 版本頁面,原因有 2 個
日期:2025-02-18
href
工具程式在框架模式中,我們現在為您提供完全型別安全的 href
工具程式,為您提供路徑自動完成的溫暖感受,以及應用程式中連結的參數驗證
import { href } from "react-router";
export default function Component() {
const link = href("/blog/:slug", { slug: "my-first-post" });
// ^ type-safe! ^ Also type-safe!
return (
<main>
<Link to={href("/products/:id", { id: "asdf" })} />
<NavLink to={href("/:lang?/about", { lang: "en" })} />
</main>
);
}
如果您傳遞錯誤的路徑值或錯誤的參數值,現在會收到型別錯誤
const badPath = href("/not/a/valid/path");
// ^ Error!
const badParam = href("/blog/:slug", { oops: "bad param" });
// ^ Error!
此版本增強了在搭配其他以「SPA 模式」運作的路徑一起使用預先渲染路徑的能力,當使用 ssr:false
進行預先渲染時。
ssr:false
但沒有 prerender
設定,則這會被視為「SPA 模式」,且產生的 index.html
檔案將僅渲染到根路由,並且能夠為任何有效的應用程式路徑進行水合ssr:false
並使用 prerender
設定,但不包含 /
路徑(即 prerender: ['/blog/post']
),那麼我們仍然會產生「SPA 模式」index.html
檔案,該檔案可以為應用程式中的任何路徑進行水合ssr:false
並在 prerender
設定中包含 /
路徑,則產生的 index.html
檔案將特定於根索引路由,因此我們現在也會在 __spa-fallback.html
中產生一個單獨的「SPA 模式」檔案,您可以為非預先渲染的路徑提供服務/水合如需更多資訊,請參閱 預先渲染 文件以取得更多資訊。
loader
SPA 模式過去禁止在所有路由中使用 loader,以便我們可以為應用程式中的任何路徑進行水合。但是,由於根路由始終在建置時渲染,因此我們可以解除對根路由的此限制。
為了在預先渲染期間使用您的建置時 loader 資料,我們現在也將 loaderData
公開為路由上 HydrateFallback
元件的選用屬性
HydrateFallback
因為子路由正在載入而渲染,就會定義此屬性HydrateFallback
因為路由本身具有自己的水合 clientLoader
而渲染,則此屬性將為 undefined
react-router
- 新的型別安全 href
工具程式,保證連結指向應用程式中的實際路徑 (#13012)@react-router/dev
- 當使用 ssr:false
預先渲染 /
路由時,產生「SPA 回退」HTML 檔案 (#12948)@react-router/dev
- 允許在 SPA 模式的根路由中使用 loader
,因為它可以在建置時呼叫/伺服器渲染 (#12948)Route.HydrateFallbackProps
現在也接收 loaderData
react-router
- 針對所有 ssr:false
應用程式而非僅限「SPA 模式」停用延遲路由探索,因為沒有執行階段伺服器來服務搜尋參數設定的 __manifest
請求 (#12894)ssr:false
應用程式prerender
情境中,我們會預先渲染 /__manifest
檔案,但這會對靜態檔案伺服器行為做出一些不必要的假設react-router
- 當處於 SPA 模式時,不要套用單一擷取重新驗證取消最佳化,因為沒有伺服器 HTTP 請求 (#12948)react-router
- 正確處理跨預先渲染/SPA 邊界的重新驗證 (#13021).data
請求,因為請求將會 404ssr:false
模式中的所有 loader
資料都是靜態的,因為它是在建置時產生的clientLoader
才能執行任何動態操作loader
而沒有 clientLoader
,我們預設會停用重新驗證,因為沒有新資料要擷取dataStrategy
中沒有具有 shouldLoad=true
的伺服器 loader,我們會短路並略過單一擷取 .data
請求邏輯.data
請求react-router
- 當設定 ssr:false
時,使開發伺服器行為與靜態檔案伺服器行為一致 (#12948)prerender
設定時,僅 SSR 下降到根目錄 HydrateFallback
(SPA 模式)prerender
設定但目前路徑未預先渲染時,僅 SSR 下降到根目錄 HydrateFallback
(SPA 回退).data
請求傳回 404 到非預先渲染的路徑react-router
- 提高框架模式中 CSS 側邊效果的預先擷取效能 (#12889)react-router
- 正確處理延遲路由探索中斷的 manifest 請求 (#12915)@react-router/dev
- 處理 Vite 設定中的自訂 envDir
(#12969)@react-router/dev
- 修正 CLI 剖析,以允許無引數 npx react-router
用法 (#12925)@react-router/dev
- 使用 prerender:true
時,略過僅限動作的資源路由 (#13004)@react-router/dev
- 當使用 ssr:false
時,增強無效匯出偵測 (#12948)headers
/action
函式在所有 ssr:false
路由中都是禁止的,因為不會有執行階段伺服器來執行它們loader
函式更細緻,並且取決於給定的路由是否已預先渲染ssr:false
且沒有 prerender
設定時,只有 root
路由可以具有 loader
ssr:false
且具有 prerender
設定時,只有與 prerender
路徑比對的路由可以具有 loader
@react-router/dev
- 在 ssr:false
+ prerender
應用程式的邊緣案例情境中,於建置時發生錯誤:(#13021)loader
(沒有 clientLoader
)loaderData
,因為沒有伺服器可以執行 loader
clientLoader
或預先渲染子路徑來解決clientLoader
,則在非預先渲染路徑上呼叫 serverLoader()
將會擲回 404@react-router/dev
- 將預先渲染的資源路由 .data
檔案限制為僅限目標路由 (#13004)@react-router/dev
- 修正二進位檔案的預先渲染 (#13039)@react-router/dev
- 修正重複參數的型別產生 (#13012)/a/:id/b/:id?/c/:id
這樣的路徑模式,最後一個 :id
將在 useParams
和 params
屬性中設定 id
的值/a/1/b/2/c/3
將導致執行階段的值為 { id: 3 }
/a/1/b/2/c/3
產生的型別類似於 { id: [1,2,3] }
。/a/1/b/2/c/3
現在產生的型別類似於 { id: 3 }
。@react-router/dev
- 修正載入 package.json
以用於 react-router --version
的路徑 (#13012)react-router
- 新增 unstable_SerializesTo
品牌型別,供函式庫作者註冊可由 React Router 串流格式 (turbo-stream
) 序列化的型別 (#12264)@react-router/dev
- 透過 future.unstable_splitRouteModules
在框架模式中新增不穩定支援以分割路由模組 (#11871)@react-router/dev
- 新增 future.unstable_viteEnvironmentApi
標誌以啟用實驗性的 Vite 環境 API 支援 (#12936)create-react-router
react-router
@react-router/architect
@react-router/cloudflare
@react-router/dev
@react-router/express
@react-router/fs-routes
@react-router/node
@react-router/remix-config-routes-adapter
@react-router/serve
完整更新日誌: v7.1.5...v7.2.0
日期:2025-01-31
react-router
- 修正透過 #12800 在 7.1.4
中引入的回歸問題,該問題導致在使用延遲路由探索 (patchRoutesOnNavigation
) 的應用程式中,導航至 splat 路由內的 hash 路由時發生問題 (#12927)完整更新日誌: v7.1.4...v7.1.5
日期:2025-01-30
@react-router/dev
- 當使用 unstable_optimizeDeps
future flag 時,正確解析 Windows 檔案路徑以掃描 Vite 的依賴項最佳化 (#12637)@react-router/dev
- 修正使用自訂伺服器時的預先渲染 - 先前我們最終嘗試匯入使用者的自訂伺服器,但實際上我們想要匯入虛擬伺服器建置模組 (#12759)react-router
- 正確處理單一擷取回應中無法包含主體的狀態碼 (204 等) (#12760)react-router
- 當擲回 data()
結果時,正確地將標頭作為 errorHeaders
冒泡 (#12846)headers
傳回,則避免重複 Set-Cookie
標頭react-router
- 停止在傳回原始字串/物件的資源路由上發生錯誤,而是將它們序列化為 text/plain
或 application/json
回應 (#12848).data
副檔名的資源路由存取時.data
請求存取時,它們仍將透過 turbo-stream
編碼react-router
- 最佳化延遲路由探索路徑探索,以偏好在 body
層級的單一 querySelectorAll
呼叫,而不是在子樹層級的多個呼叫 (#12731)react-router
- 透過在可能的情況下略過多餘的 matchRoutes
呼叫來最佳化路由比對 (#12800, #12882)react-router
- 內部重組以清理一些重複的路由模組型別 (#12799)完整更新日誌: v7.1.3...v7.1.4
日期:2025-01-17
@react-router/dev
- 修正 reveal
和 routes
CLI 命令 (#12745)完整更新日誌: v7.1.2...v7.1.3
日期:2025-01-16
react-router
- 修正擷取器卸載時資料層中擷取器資料清理的問題 (#12681)react-router
- 不要依賴 symbol
來篩選 loader 資料中的 redirect
回應 (#12694)error TS4058: Return type of exported function has or is using name 'redirectSymbol' from external module "node_modules/..." but cannot be named.
symbol
s 不再用於 redirect
回應型別,這些錯誤應該不再存在@react-router/dev
- 修正 Vite v6 中的預設外部條件 (#12644)@react-router/dev
- 修正路徑遺失前導斜線時預先渲染 html/資料檔案的不符問題 (#12684)@react-router/dev
- 在執行階段啟用時使用 module-sync
伺服器條件。這修正了使用對 React Router 具有對等依賴項的函式庫時,在 Node 22.10.0+ 上開發期間的 React context 不符問題 (例如 useHref() may be used only in the context of a <Router> component.
) (#12729)@react-router/dev
- 修正 react-refresh
原始碼地圖 (#12686)完整變更日誌: v7.1.1...v7.1.2
日期: 2024-12-23
@react-router/dev
- 修正當可選參數傳遞至 CLI 時發生的崩潰問題 (#12609)完整變更日誌: v7.1.0...v7.1.1
日期: 2024-12-20
react-router
- 拋出未封裝的 Single Fetch redirect
以與 pre-Single Fetch 行為一致 (#12506)react-router
- 在推斷 loader 資料型別時忽略 redirects (#12527)react-router
- 移除 <Link prefetch>
警告,此警告在惰性路由發現世界中會產生誤報 (#12485)create-react-router
- 修正遺失的 fs-extra
相依性問題 (#12556)@react-router/dev
/@react-router/serve
- 如果尚未設定,則正確初始化 NODE_ENV
,以與 React 19 相容 (#12578)@react-router/dev
- 從 ServerRouter
移除剩餘/未使用的 abortDelay
屬性,並更新預設的 entry.server.tsx
以使用 Single Fetch 的新 streamTimeout
值 (#12478)abortDelay
功能已在 v7 中移除,因為它與 Remix v2 的 defer
實作相關聯,但此屬性的移除被遺漏了entry.server
檔案中使用此屬性,則您的應用程式可能沒有如預期般中止串流,並且您需要採用使用 Single Fetch 引入的新 streamTimeout
值@react-router/fs-routes
- 如果路由目錄遺失,則在 flatRoutes
中拋出錯誤 (#12407)create-react-router
react-router
@react-router/architect
@react-router/cloudflare
@react-router/dev
@react-router/express
@react-router/fs-routes
@react-router/node
@react-router/remix-config-routes-adapter
@react-router/serve
完整變更日誌: v7.0.2...v7.1.0
日期: 2024-12-02
react-router
- 暫時僅在匯出地圖中使用一個建置版本,以便套件可以對 react router 具有 peer dependency (#12437)@react-router/dev
- 支援 moduleResolution
Node16
和 NodeNext
(#12440)@react-router/dev
- 為子路由產生寬鬆的 matches
和 params
型別 (#12397)matches
包含子路由比對,而 params
包含子路由路徑參數matches
和 params
中的目前路由產生型別完整變更日誌: v7.0.1...v7.0.2
日期: 2024-11-22
@react-router/dev
- 確保在 Vite 開發伺服器重新啟動時清理 typegen 檔案監看器 (#12331)@react-router/dev
- 將路由 error
作為 prop 傳遞至 ErrorBoundary
(#12338)完整變更日誌: v7.0.0...v7.0.1
日期: 2024-11-21
react-router-dom
、@remix-run/react
、@remix-run/server-runtime
和 @remix-run/router
已摺疊到 react-router
套件中react-router-dom
仍然在 v7 中發佈,作為從 react-router
重新匯出所有內容@remix-run/cloudflare-pages
和 @remix-run/cloudflare-workers
已摺疊到 @react-router/cloudflare
套件中react-router-dom-v5-compat
和 react-router-native
套件已從 v7 開始移除Remix v2 過去透過各種執行時期套件 (node
、cloudflare
、deno
) 重新匯出所有常見的 @remix-run/server-runtime
API,以便您在 package.json
中不需要額外的 @remix-run/server-runtime
相依性。隨著套件摺疊到 react-router
中,這些常見的 API 現在不再透過執行時期介面卡重新匯出。您應該從 react-router
匯入所有常見的 API,並且僅從執行時期套件匯入執行時期特定的 API
// Runtime-specific APIs
import { createFileSessionStorage } from "@react-router/node";
// Runtime-agnostic APIs
import { redirect, useLoaderData } from "react-router";
以下 API 已在 React Router v7 中移除
json
defer
unstable_composeUploadHandlers
unstable_createMemoryUploadHandler
unstable_parseMultipartFormData
React Router v7 需要以下最低版本
node@20
installGlobals
方法來 polyfill fetch
APIreact@18
, react-dom@18
Remix 和 React Router 遵循 API 開發策略,利用「未來標誌」來避免在主要版本中引入大量重大變更。相反地,重大變更在次要版本中透過標誌引入,允許使用者在其方便時選擇加入。在下一個主要版本中,所有未來標誌行為都將成為預設行為。
以下先前標記的行為現在是 React Router v7 中的預設行為
future.v7_relativeSplatPath
future.v7_startTransition
future.v7_fetcherPersist
future.v7_normalizeFormMethod
future.v7_partialHydration
future.v7_skipActionStatusRevalidation
future.v3_fetcherPersist
future.v3_relativeSplatPath
future.v3_throwAbortReason
future.v3_singleFetch
future.v3_lazyRouteDiscovery
future.v3_optimizeDeps
Remix Vite 外掛程式是使用 React Router v7 建置全堆疊 SSR 應用程式的正確方式。以前基於 esbuild
的編譯器不再可用。
重新命名 vitePlugin
和 cloudflareDevProxyVitePlugin
對於遷移到 React Router 的 Remix 使用者,vitePlugin
和 cloudflareDevProxyVitePlugin
匯出已重新命名和移動 (#11904)
-import {
- vitePlugin as remix,
- cloudflareDevProxyVitePlugin,
-} from "@remix/dev";
+import { reactRouter } from "@react-router/dev/vite";
+import { cloudflareDevProxy } from "@react-router/dev/vite/cloudflare";
移除 manifest
選項
對於遷移到 React Router 的 Remix 使用者,Vite 外掛程式的 manifest
選項已移除。manifest
選項已被更強大的 buildEnd
hook 取代,因為它傳遞了 buildManifest
參數。如果需要,您仍然可以將建置 manifest 寫入磁碟,但您很可能會發現將任何取決於建置 manifest 的邏輯寫入 buildEnd
hook 本身更方便。( #11573)
如果您正在使用 manifest
選項,您可以使用寫入 manifest 到磁碟的 buildEnd
hook 來取代它,如下所示
// react-router.config.ts
import { type Config } from "@react-router/dev/config";
import { writeFile } from "node:fs/promises";
export default {
async buildEnd({ buildManifest }) {
await writeFile(
"build/manifest.json",
JSON.stringify(buildManifest, null, 2),
"utf-8"
);
},
} satisfies Config;
由於 React 19 將首次支援在渲染階段處理 promise (透過 React.use
和 useAction
),我們現在很樂意公開先前傳回 undefined
的 API 的 promise
useNavigate()
useSubmit()
useFetcher().load
useFetcher().submit
useRevalidator().revalidate()
routes.ts
當使用 React Router Vite 外掛程式時,路由在 app/routes.ts
中定義。路由設定透過 routes
匯出公開,符合 RouteConfig
型別。路由輔助函式 route
、index
和 layout
提供更輕鬆的宣告式型別安全路由定義。
// app/routes.ts
import {
type RouteConfig,
route,
index,
layout,
} from "@react-router/dev/routes";
export const routes: RouteConfig = [
index("./home.tsx"),
route("about", "./about.tsx"),
layout("./auth/layout.tsx", [
route("login", "./auth/login.tsx"),
route("register", "./auth/register.tsx"),
]),
route("concerts", [
index("./concerts/home.tsx"),
route(":city", "./concerts/city.tsx"),
route("trending", "./concerts/trending.tsx"),
]),
];
對於遷移到 React Router 的 Remix 使用者,您仍然可以使用 @react-router/fs-routes
套件在 routes.ts
中設定檔案系統路由。重現預設 Remix 設定的最小路由設定如下所示
// app/routes.ts
import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";
export const routes: RouteConfig = flatRoutes();
如果您想要從檔案系統路由遷移到基於設定的路由,您可以透過將非同步 flatRoutes
函式的結果展開到基於設定的路由陣列中來混合和比對方法。
// app/routes.ts
import { type RouteConfig, route } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";
export const routes: RouteConfig = [
// Example config-based route:
route("/hello", "./routes/hello.tsx"),
// File system routes scoped to a different directory:
...(await flatRoutes({
rootDirectory: "fs-routes",
})),
];
如果您正在使用 Remix 的 routes
選項來使用替代的檔案系統路由慣例,您可以使用 @react-router/remix-config-routes-adapter
將這些慣例調整為新的 RouteConfig
格式。
例如,如果您在 Remix v2 中使用 Remix v1 路由慣例,您可以將 @react-router/remix-config-routes-adapter
與 @remix-run/v1-route-convention
結合,以將其調整為 React Router
// app/routes.ts
import { type RouteConfig } from "@react-router/dev/routes";
import { remixConfigRoutes } from "@react-router/remix-config-routes-adapter";
import { createRoutesFromFolders } from "@remix-run/v1-route-convention";
export const routes: RouteConfig = remixConfigRoutes(async (defineRoutes) => {
return createRoutesFromFolders(defineRoutes, {
ignoredFilePatterns: ["**/.*", "**/*.css"],
});
});
另請注意,如果您正在使用 Remix 的 routes
選項來定義基於設定的路由,您也可以使用 @react-router/remix-config-routes-adapter
以最小的程式碼變更將這些路由調整為新的 RouteConfig
格式。雖然這提供快速的遷移路徑,但我們建議將任何基於設定的路由從 Remix 遷移到新的 RouteConfig
格式,因為這是一個相當簡單的遷移。
// app/routes.ts
-import { type RouteConfig } from "@react-router/dev/routes";
+import { type RouteConfig, route } from "@react-router/dev/routes";
-import { remixConfigRoutes } from "@react-router/remix-config-routes-adapter";
-export const routes: RouteConfig = remixConfigRoutes(async (defineRoutes) => {
- defineRoutes((route) => {
- route("/parent", "./routes/parent.tsx", () => [
- route("/child", "./routes/child.tsx"),
- ]);
- });
-});
+export const routes: RouteConfig = [
+ route("/parent", "./routes/parent.tsx", [
+ route("/child", "./routes/child.tsx"),
+ ]),
+];
React Router 現在為每個路由模組產生型別,並將型別化的 props 傳遞給路由模組元件匯出 (#11961, #12019)。您可以透過從 ./+types/<route filename without extension>
匯入這些型別來存取它們。
請參閱 操作指南 > 路由模組型別安全 和 說明 > 型別安全 以取得更多詳細資訊。
React Router v7 在 vite 外掛程式中包含新的 prerender
設定,以支援 SSG 用例。這將在建置時預先渲染您的 .html
和 .data
檔案,因此您可以在執行時期從執行中的伺服器或 CDN 靜態地提供它們 (#11539)
export default defineConfig({
plugins: [
reactRouter({
async prerender({ getStaticPaths }) {
let slugs = await fakeGetSlugsFromCms();
return [
...getStaticPaths(),
...slugs.map((slug) => `/product/${slug}`),
];
},
}),
tsconfigPaths(),
],
});
async function fakeGetSlugsFromCms() {
await new Promise((r) => setTimeout(r, 1000));
return ["shirt", "hat"];
}
react-router
)defer
實作,改為透過 single fetch 和 turbo-stream
使用原始 promise (#11744)defer
AbortedDeferredError
type TypedDeferredData
UNSAFE_DeferredData
UNSAFE_DEFERRED_SYMBOL
react-router
中 (#11505)@remix-run/router
react-router-dom
@remix-run/server-runtime
@remix-run/testing
react-router-dom
套件維護旨在簡化採用,但它只是重新匯出 react-router
中的所有 APIfuture.v7_startTransition
標誌 (#11696)future.v7_normalizeFormMethod
未來標誌 (#11697)@remix-run/router
公開 API 的以下匯出AgnosticDataIndexRouteObject
AgnosticDataNonIndexRouteObject
AgnosticDataRouteMatch
AgnosticDataRouteObject
AgnosticIndexRouteObject
AgnosticNonIndexRouteObject
AgnosticRouteMatch
AgnosticRouteObject
TrackedPromise
unstable_AgnosticPatchRoutesOnMissFunction
Action
-> 透過 react-router
作為 NavigationType
匯出Router
作為 RemixRouter
匯出,以與 RR 的 <Router>
區分getToPathname
(@private
)joinPaths
(@private
)normalizePathname
(@private
)resolveTo
(@private
)stripBasename
(@private
)createBrowserHistory
-> 傾向於使用 createBrowserRouter
createHashHistory
-> 傾向於使用 createHashRouter
createMemoryHistory
-> 傾向於使用 createMemoryRouter
createRouter
createStaticHandler
-> 傾向於使用 RR Dom 中的 wrapper createStaticHandler
getStaticContextFromError
react-router
公開 API 的以下匯出Hash
Pathname
Search
@remix-run/router
套件中移除 future.v7_prependBasename
(#11726)@remix-run/router
套件中移除 future.v7_throwAbortReason
(#11728)exports
欄位新增至所有套件 (#11675)RemixContext
重新命名為 FrameworkContext
(#11705)PrefetchPageDescriptor
由 PageLinkDescriptor
取代 (#11960)future.v7_partialHydration
標誌 (#11725)<RouterProvider fallbackElement>
propfallbackElement
移動到根路由上的 hydrateFallbackElement
/HydrateFallback
future.v7_partialHydration
的情況下 (當使用 fallbackElement
時),state.navigation
在初始載入期間已填入future.v7_partialHydration
,state.navigation
在初始載入期間保持 "idle"
狀態future.v7_relativeSplatPath
未來標誌 (#11695)v7_skipActionErrorRevalidation
v3_fetcherPersist
、v3_relativeSplatPath
、v3_throwAbortReason
createRemixStub
重新命名為 createRoutesStub
(#11692)@remix-run/router
已棄用的 detectErrorBoundary
選項,改為使用 mapRouteProperties
(#11751)react-router/dom
子路徑匯出,以正確啟用 react-dom
作為選用的 peerDependency
(#11851)<RouterProvider>
中盲目地 import ReactDOM from "react-dom"
以存取 ReactDOM.flushSync()
,因為這會在非 DOM 環境中中斷 createMemoryRouter
用例react-router/dom
匯入,以取得可使用 ReactDOM.flushSync()
的正確元件entry.client.tsx
中使用此程式碼import { HydratedRouter } from 'react-router/dom'
createBrowserRouter
/createHashRouter
import { RouterProvider } from "react-router/dom"
future.v7_fetcherPersist
標誌 (#11731)undefined
(#11680, #12057)entry.client
中使用 createRemixRouter
/RouterProvider
而不是 RemixBrowser
(#11469)json
工具程式 (#12146)Response.json
@react-router/*
)future.v3_singleFetch
標誌 (#11522)installGlobals()
,因為這應該不再必要exports
欄位新增至所有套件 (#11675)react-router
中的 API (#11702)crypto
全域變數react-router
而不是平台特定的套件提供:(#11837)createCookie
createCookieSessionStorage
createMemorySessionStorage
createSessionStorage
@remix-run/node
中的 installGlobals
函式已更新為定義 globalThis.crypto
,使用 Node 的 require('node:crypto').webcrypto
實作createCookieFactory
createSessionStorageFactory
createCookieSessionStorageFactory
createMemorySessionStorageFactory
@remix-run/router
、@remix-run/server-runtime
和 @remix-run/react
先前重複的型別現在都位於 react-router
中,因此將它們合併 (#12177)LoaderFunction
、LoaderFunctionArgs
、ActionFunction
、ActionFunctionArgs
、DataFunctionArgs
、RouteManifest
、LinksFunction
、Route
、EntryRoute
RouteManifest
型別現在稍微嚴格,因為它使用先前的 @remix-run/router
RouteManifest
Record<string, Route> -> Record<string, Route | undefined>
AppData
型別,改為在少數使用它的位置內嵌 unknown
ServerRuntimeMeta*
型別,改為使用它們重複自的 Meta*
型別Route.*
型別Route.*
型別useFetcher
先前有一個選用的泛型 (主要由 Remix v2 使用),預期資料型別typeof loader
/typeof action
)useFetcher<LoaderData>()
useFetcher<typeof loader>()
cookie
相依性更新為 ^1.0.1
- 請參閱 版本說明 以取得任何重大變更 (#12172)@react-router/cloudflare
- 對於遷移到 React Router 的 Remix 使用者,@remix-run/cloudflare-pages
中的所有匯出現在都為 @react-router/cloudflare
套件中的 React Router 使用者提供。Cloudflare Pages 不再有單獨的套件。( #11801)@react-router/cloudflare
- @remix-run/cloudflare-workers
套件已被棄用。遷移到 React Router 的 Remix 使用者應直接使用 @react-router/cloudflare
套件。如需如何在 Cloudflare Workers 環境中使用 @react-router/cloudflare
的指南,請參閱 Cloudflare Workers 範本。( #11801)@react-router/dev
- 對於遷移到 React Router 的 Remix 使用者,vitePlugin
和 cloudflareDevProxyVitePlugin
匯出已重新命名和移動。( #11904)@react-router/dev
- 對於遷移到 React Router 且使用 Vite 外掛程式的 buildEnd
hook 的 Remix 使用者,已解析的 reactRouterConfig
物件不再包含 publicPath
屬性,因為這屬於 Vite,而不是 React Router (#11575)@react-router/dev
- 對於遷移到 React Router 的 Remix 使用者,Vite 外掛程式的 manifest
選項已移除 (#11573)@react-router/dev
- 將預設 isbot
版本更新為 v5,並停止支援 isbot@3
(#11770)package.json
中有 isbot@4
或 isbot@5
package.json
中有 isbot@3
,並且您的 repo 中有自己的 entry.server.tsx
檔案isbot@5
package.json
中有 isbot@3
,並且您的 repo 中沒有自己的 entry.server.tsx
檔案package.json
中升級到 isbot@5
@react-router/dev
- 對於遷移到 React Router 的 Remix 使用者,Vite manifests (即 .vite/manifest.json
) 現在寫入每個建置子目錄中,例如 build/client/.vite/manifest.json
和 build/server/.vite/manifest.json
,而不是 build/.vite/client-manifest.json
和 build/.vite/server-manifest.json
。這表示建置輸出現在更接近您對典型 Vite 專案的期望。( #11573)build/.vite
目錄,以避免在生產環境中意外提供它們,特別是從用戶端建置版本。後來透過額外的邏輯進行了改進,該邏輯在建置過程結束時刪除了這些 Vite manifest 檔案,除非在應用程式的 Vite 設定中啟用了 Vite 的 build.manifest
。這大大降低了在生產環境中意外提供 Vite manifests 的風險,因為它們僅在明確要求時才存在。因此,我們現在可以假設使用者會知道他們需要自行管理這些額外檔案,並且 React Router 可以安全地產生更標準的 Vite 建置輸出。react-router
- 路由元件匯出的 props 中的 Params、loader 資料和 action 資料 (#11961)react-router
- 新增路由模組型別產生 (#12019)react-router
- 移除重複的 RouterProvider
實作 (#11679)react-router
- 穩定 unstable_dataStrategy
(#11969)react-router
- 穩定 unstable_patchRoutesOnNavigation
(#11970)react-router
- 在使用 Remix SSR 時,將預先擷取支援新增至 Link
/NavLink
(#11402)react-router
- 增強 ScrollRestoration
,使其可以在 SSR'd 文件載入時正確還原 (#11401)@react-router/dev
- 在 React Router vite 外掛程式中新增對 prerender
設定的支援,以支援現有的 SSG 用例 (#11539)@react-router/dev
- 移除與 Single Fetch 非同步 hydration 方法不相容的內部 entry.server.spa.tsx
實作 (#11681)@react-router/serve
:更新 express.static
設定以支援新的 prerender
API (#11547)build/client/assets
資料夾中的資產與以前一樣提供服務,具有 1 年不可變的 Cache-Control
標頭.html
和 .data
檔案,不會使用特定的 Cache-Control
標頭提供服務.data
檔案以 Content-Type: text/x-turbo
提供服務express.static
新增此內容時,它似乎也會將 Cache-Control: public, max-age=0
新增至 .data
檔案substr
取代為 substring
(#12080)react-router
- 修正從 loaders/actions 使用 data()
傳回的 redirects 問題 (#12021)@react-router/dev
- 啟用資源路由的預先渲染 (#12200)@react-router/dev
- 解析相對於平面輸出檔案結構的設定目錄 (#12187)react-router
@react-router/architect
@react-router/cloudflare
@react-router/dev
@react-router/express
@react-router/fs-routes
@react-router/node
@react-router/remix-config-routes-adapter
@react-router/serve
完整變更日誌: v6.28.0...v7.0.0
日期:2025-01-30
signal
作為 patchRoutesOnNavigation
的參數 (#12900)data()
結果時正確地 bubble 標頭 (#12845)matchRoutes
呼叫來最佳化路由比對 (#12169)patchRoutesOnNavigation
path
參數中移除搜尋參數 (#12899)完整變更日誌: v6.28.2...v6.29.0
日期:2025-01-16
future.v7_fetcherPersist
時手動 fetcher key
的使用問題 (#12674)完整變更日誌: v6.28.1...v6.28.2
日期: 2024-12-20
false
來選擇退出 v7 棄用警告 (#12441)完整變更日誌: v6.28.0...v6.28.1
日期: 2024-11-06
json
/defer
添加棄用警告,建議改為返回原始物件完整變更日誌: v6.27.0...v6.28.0
日期:2024-10-11
此版本穩定了一些「不穩定」的 API,為即將發布的 pending React Router v7 版本做準備(請參閱 這些 文章 以取得更多資訊)
unstable_dataStrategy
→ dataStrategy
(createBrowserRouter
和朋友們) (文件)unstable_patchRoutesOnNavigation
→ patchRoutesOnNavigation
(createBrowserRouter
和朋友們) (文件)unstable_flushSync
→ flushSync
(useSubmit
, fetcher.load
, fetcher.submit
) (文件)unstable_viewTransition
→ viewTransition
(<Link>
, <Form>
, useNavigate
, useSubmit
) (文件)unstable_flushSync
選項 (#11989)unstable_useViewTransitionState
Hook 的 unstable_viewTransition
選項 (#11989)unstable_dataStrategy
(#11974)unstable_patchRoutesOnNavigation
(#11973)PatchRoutesOnNavigationFunctionArgs
型別 (#11967)?index
參數的錯誤 (#12003)useFormAction
錯誤 - 當移除 ?index
參數時,不會保留其他非 Remix 的 index
參數 (#12003)preventScrollReset
的錯誤 (#11999)console.error
(#12050)partialHydration
的錯誤 (#12070)patchRoutesOnNavigation
呼叫的問題 (#12055)unstable_
API 中的此行為,這可能是一個重大變更patchRoutesOnNavigation
呼叫,以便具有相同開始/結束的多個導航只會執行一次函式並使用相同的 Promisepatch
在導航中斷(且 request.signal
中止)時短路的情況相矛盾,因為第一次調用的 patch
將無操作import()
的非同步路由將已經自動快取 - 如果沒有,使用者也很容易在使用者空間中實作此快取unstable_patchRoutesOnNavigation
中移除內部 discoveredRoutes
FIFO 佇列 (#11977)unstable_
API 中的此行為,這可能是一個重大變更patchRoutesOnNavigation
內部實作自己的快取PatchRoutesOnNavigationFunction
的 patch
方法中 RouteObject
的類型,使其不會期望傳遞給 patch
的不可知路由物件 (#11967)patchRoutesOnNavigation
拋出的錯誤直接暴露給 useRouteError
,而不是將它們包裝在 400 ErrorResponse
實例中 (#12111)完整變更日誌: v6.26.2...v6.27.0
日期:2024-09-09
unstable_dataStrategy
API 以允許更進階的實作 (#11943)unstable_dataStrategy
,請仔細審閱,因為這包含此 API 的重大變更unstable_HandlerResult
重新命名為 unstable_DataStrategyResult
unstable_dataStrategy
的回傳簽名從 unstable_DataStrategyResult[]
的平行陣列(與 matches
平行)變更為 routeId => unstable_DataStrategyResult
的鍵/值物件match.shouldLoad
)handlerOverride
回傳/拋出結果,而不是回傳 DataStrategyResult
handlerOverride
的回傳值(或拋出的錯誤)將被包裝到 DataStrategyResult
中,並從 match.resolve
回傳match.resolve()
的結果彙整到最終結果物件中,您應該不需要考慮 DataStrategyResult
類型handlerOverride
內部手動填寫結果物件,則您需要指派 DataStrategyResult
作為值,以便 React Router 知道它是成功執行還是錯誤(請參閱文件中的範例以了解詳細資訊)unstable_dataStrategy
新增了 fetcherKey
參數,以區分導航和 fetcher 呼叫blocker.proceed
時的 blocker 用法 (#11930)完整變更日誌: v6.26.1...v6.26.2
日期:2024-08-15
unstable_patchRoutesOnMiss
重新命名為 unstable_patchRoutesOnNavigation
以符合新的行為 (#11888)unstable_patchRoutesOnNavigation
邏輯,以便在我們比對到具有動態參數或 splat 段的路由時呼叫該方法,以防存在我們尚未發現的更高分靜態路由 (#11883)unstable_patchRoutesOnNavigation
的路徑的內部 FIFO 佇列,以便我們不會對後續導航到相同路徑重新呼叫完整變更日誌: v6.26.0...v6.26.1
日期:2024-08-01
replace(url, init?)
作為 redirect(url, init?)
的替代方案,在用戶端導航重新導向時執行 history.replaceState
而不是 history.pushState
(#11811)unstable_data()
API (#11836)createStaticHandler.query()
,以允許 loader/action 回傳任意資料以及自訂 status
/headers
,而無需強制將資料序列化為 Response
實例unstable_dataStrategy
進行更進階的序列化策略,例如在 Remix Single Fetch 中透過 turbo-stream
進行序列化HandlerResult
中移除 status
欄位unstable_dataStrategy
回傳特定的 status
,您應該改為透過 unstable_data()
執行future.v7_partialHydration
與 unstable_patchRoutesOnMiss
一起使用時的初始 hydration 行為 (#11838)router.state.matches
現在將包含任何部分比對,以便我們可以渲染祖先 HydrateFallback
元件完整變更日誌: v6.25.1...v6.26.0
日期:2024-07-17
RouterProvider
內部元件以減少不必要的重新渲染 (#11803)完整變更日誌: v6.25.0...v6.25.1
日期:2024-07-16
v7_skipActionErrorRevalidation
此版本將 future.unstable_skipActionErrorRevalidation
標誌穩定為 future.v7_skipActionErrorRevalidation
,為即將發布的 React Router v7 版本做準備。
4xx/5xx
Response
的 action 預設將不會觸發重新驗證shouldRevalidate
的 unstable_actionStatus
參數穩定為 actionStatus
future.unstable_skipActionErrorRevalidation
穩定為 future.v7_skipActionErrorRevalidation
(#11769)useMatch
內部的路徑,以便比對/參數反映解碼後的參數 (#11789)unstable_patchRoutesOnMiss
拋出的錯誤冒泡 (#11786)unstable_patchRoutesOnMiss
,且在伺服器上比對到 splat 路由時的 hydration 問題 (#11790)完整變更日誌: v6.24.1...v6.25.0
日期:2024-07-03
polyfill.io
參考,因為該網域已出售,並且後來被確定為提供惡意軟體 (#11741)
NavLinkRenderProps
類型,以便更輕鬆地輸入自訂 NavLink
回呼 (#11553)future.v7_relativeSplatPath
時,正確解析路徑路由子項中 splat 路由中的相對路徑 (#11633)router.routes
身分/重排 (#11740)完整變更日誌: v6.24.0...v6.24.1
日期:2024-06-24
我們非常興奮地在 v6.24.0
中發布我們用於「延遲路由探索」的新 API!有關背景資訊,請查看原始的 RFC。tl;dr; 是自從我們在 v6.4 中透過 <RouterProvider>
引入資料 API 以來,我們一直有點失望的是,其中一個權衡是缺乏與我們在 <BrowserRouter>
/<Routes>
應用程式中擁有的引人注目的程式碼分割故事。我們在 v6.9.0
中透過 route.lazy
朝著改進該故事邁出了一小步,但在 v6.24.0
中,我們已經走完了剩下的路。
透過「戰爭迷霧」,您現在可以透過傳遞給 createBrowserRouter
(及其記憶體/雜湊對應項)的新 unstable_patchRoutesOnMiss
選項,延遲載入路由樹的部分。這為您提供了一種掛鉤到 React Router 無法比對給定路徑的位置,並在導航(或 fetcher 呼叫)期間將新路由修補到路由樹中的方法。
這是一個非常小的範例,但請參閱 文件 以取得更多資訊和使用案例
const router = createBrowserRouter(
[
{
id: "root",
path: "/",
Component: RootComponent,
},
],
{
async unstable_patchRoutesOnMiss({ path, patch }) {
if (path === "/a") {
// Load the `a` route (`{ path: 'a', Component: A }`)
let route = await getARoute();
// Patch the `a` route in as a new child of the `root` route
patch("root", [route]);
}
},
}
);
fetcher.submit
類型 - 移除不正確的 navigate
/fetcherKey
/unstable_viewTransition
選項,因為它們僅與 useSubmit
相關 (#11631)<StaticRouter>
的 falsy location.state
值 (#11495)完整變更日誌: v6.23.1...v6.24.0
日期:2024-05-10
<Await>
解析 undefined
(#11513)document.startViewTransition
可用性時,新增防禦性 document
檢查 (#11544)react-router-dom/server
匯入改回 react-router-dom
而不是 index.ts
(#11514)@remix-run/router
- 支援 staticHandler.queryRoute
上的 unstable_dataStrategy
(#11515)完整變更日誌: v6.23.0...v6.23.1
日期:2024-04-23
新的 unstable_dataStrategy
API 是一個低階 API,專為需要控制 loader
/action
函式的資料策略的進階使用案例而設計。預設實作是今天的行為,平行提取所有 loader,但此選項允許使用者實作更進階的資料流程,包括 Remix 「Single Fetch」、使用者空間中介軟體/內容 API、自動 loader 快取等等。請參閱 文件 以取得更多資訊。
注意:這是一個低階 API,適用於進階使用案例。這會覆寫 React Router 對 loader
/action
執行的內部處理,如果執行不正確,將會破壞您的應用程式碼。請謹慎使用並執行適當的測試。
目前,所有作用中的 loader
在任何 action
提交後都會重新驗證,無論 action
結果如何。但是,在大多數情況下,來自 action
的 4xx`/`5xx
回應表示實際上沒有資料被變更,並且重新驗證是不必要的。我們引入了一個新的 future.unstable_skipActionErrorRevalidation
標誌,它會在此處變更行為,我們計劃在未來版本的 React Router 中將其設為預設值。
啟用此標誌後,回傳/拋出 4xx`/`5xx
回應狀態的 action
將不再自動重新驗證。如果您需要在啟用此標誌後在 4xx`/`5xx
結果之後重新驗證,您仍然可以透過從 shouldRevalidate
回傳 true
來執行此操作 - 現在它也接收到新的 unstable_actionStatus
引數以及 actionResult
,以便您可以根據 action
回應的狀態做出決定,而無需將其編碼到 action 資料中。
unstable_dataStrategy
組態選項 (#11098, #11377)@remix-run/router
- 新增 future.unstable_skipActionRevalidation
未來標誌 (#11098)@remix-run/router
- SSR:為 staticHandler.query
方法新增了 skipLoaderErrorBubbling
選項,以停用靜態處理常式的錯誤冒泡,以用於 Remix 的 Single Fetch 實作 (#11098, (#11377))完整變更日誌: v6.22.3...v6.23.0
日期:2024-03-07
future.v7_partialHydration
錯誤,該錯誤會在伺服器端渲染 loader 錯誤冒泡到父邊界時,在 hydration 時重新執行邊界下方的 loader (#11324)future.v7_partialHydration
錯誤,如果路由沒有 loader,則會將路由器視為未初始化 (#11325)完整變更日誌: v6.22.2...v6.22.3
日期:2024-02-28
完整變更日誌: v6.22.1...v6.22.2
日期:2024-02-16
完整變更日誌: v6.22.0...v6.22.1
日期:2024-02-01
2021 年,HTTP Archive 推出了 Core Web Vitals 技術報告儀表板
透過結合 Chrome UX Report 26 (CrUX) 資料集中真實使用者體驗的力量與 HTTP Archive 30 中的 Web 技術偵測,我們可以了解 CMS 平台或 JavaScript 框架的選擇等架構決策如何在網站的 CWV 效能中發揮作用。
他們使用一個名為 wappalyzer
的工具,透過尋找某些腳本、全域 JS 變數或其他識別特徵來識別給定網站正在使用的技術。例如,對於 Remix 應用程式,他們 尋找全域 __remixContext
變數以識別網站是否正在使用 Remix。
我們注意到 React Router 無法可靠地識別,因為沒有可識別的全域方面。他們目前 正在尋找名稱中帶有 react-router
的外部腳本。這將識別從 CDN(例如 unpkg
)使用 React Router 的網站 - 但它會錯過**絕大多數**從 npm 登錄檔安裝 React Router 並將其捆綁到其 JS 檔案中的網站。這導致 嚴重低估 React Router 在 Web 上的使用情況。
從 6.22.0
版本開始,使用 react-router-dom
的網站將開始新增 window.__reactRouterVersion
變數,該變數將設定為 SemVer 主要版本號碼的字串值(即,window.__reactRouterVersion = "6";
),以便可以正確識別它們。
window.__reactRouterVersion
(#11222)createStaticHandler
future.v7_throwAbortReason
標誌,以在請求中止時拋出 request.signal.reason
(預設為 DOMException
),而不是 Error
,例如 new Error("query() call aborted: GET /path")
(#11104)DOMException
是在 Node v17 中新增的,因此您在 Node 16 及更低版本上不會獲得 DOMException
。getStaticContextFormError
,則尊重 ErrorResponse
狀態碼 (#11213)完整變更日誌: v6.21.3...v6.22.0
日期:2024-01-18
basename
時 NavLink
的 isPending
(#11195)Blocker
/BlockerFunction
類型中移除剩餘的 unstable_
前綴 (#11187)完整變更日誌: v6.21.2...v6.21.3
日期:2024-01-11
完整變更日誌: v6.21.1...v6.21.2
日期:2023-12-21
v7_partialHydration
時,route.lazy
在初始 SPA 載入時無法正常運作的錯誤 (#11121)submitting
階段取消掛載的持久化 fetcher 發生重新驗證的錯誤 (#11102)resolveTo
中取消重複的相對路徑邏輯 (#11097)完整變更日誌: v6.21.0...v6.21.1
日期:2023-12-13
future.v7_relativeSplatPath
我們在 6.19.0
中修正了一個 splat 路由路徑解析錯誤,但後來確定大量應用程式依賴於錯誤的行為,因此我們在 6.20.1
中還原了該修復(請參閱 #10983, #11052, #11078)。
錯誤的行為是,在 splat 路由內解析相對路徑時的預設行為會*忽略*目前路由路徑的任何 splat (*
) 部分。啟用 future 標誌後,splat 部分將包含在 splat 路由內的相對路徑邏輯中。
如需更多資訊,請參閱 useResolvedPath
文件 和/或 詳細的變更日誌條目。
我們為 @remix-run/router
新增了一個新的 future.v7_partialHydration
future 標誌,該標誌在伺服器端渲染時啟用資料路由器的部分 hydration。這允許您提供 hydrationData.loaderData
,其中包含*某些*初始比對路由 loader 的值,但並非全部。啟用此標誌後,路由器將在 router.initialize()
期間為沒有 hydration loader 資料的路由呼叫 loader
函式,並且在執行未 hydration 的路由時,它將向下渲染到最深層提供的 HydrateFallback
(最多到第一個沒有 hydration 資料的路由)。 (#11033)
future.v7_relativeSplatPath
標誌,以實作 splat 路由內相對路由的重大錯誤修復。 (#11087)future.v7_partialHydration
future 標誌,該標誌在伺服器端渲染時啟用資料路由器的部分 hydration (#11033)ErrorBoundary
中的 falsy 錯誤值 (#11071)loader
/action
函式解包回應時拋出的錯誤 (#11061)Link
/NavLink
時的 relative="path"
問題 (#11062)完整變更日誌: v6.20.1...v6.21.0
日期:2023-12-01
useResolvedPath
修復,因為大量應用程式依賴於錯誤的行為(請參閱 #11052) (#11078)6.19.0
和 6.20.0
版本中。如果您是從 6.18.0
或更早版本升級,您將不會受到此修復的影響。完整變更日誌: v6.20.0...v6.20.1
日期:2023-11-22
[!WARNING] 請使用
6.20.1
或更高版本,而不是6.20.0
。我們發現大量應用程式依賴於此版本中修復的錯誤行為 (#11045)。我們在6.20.1
中還原了該修復,並將在後續版本中在 future 標誌後面重新引入它。請參閱 #11052 以取得更多詳細資訊。
PathParam
類型 (#10719)v7_fetcherPersist
時,請勿重新驗證已卸載的 fetcher (#11044)resolveTo
路徑解析的錯誤 (#11045)getPathContributingMatches
的其他幾個程式碼路徑@remix-run/router
中移除 UNSAFE_getPathContributingMatches
匯出,因為我們在 react-router
/react-router-dom
層中不再需要它完整變更日誌:v6.19.0...v6.20.0
日期:2023-11-16
[!WARNING] 請使用
6.20.1
或更新版本,而非6.19.0
。我們發現大量應用程式依賴於此版本中已修復的錯誤行為 (#10983)。我們在6.20.1
中還原了此修復,並將在後續版本中透過未來標誌重新引入。詳情請參閱 #11052。
unstable_flushSync
API此版本為命令式 API (useSubmit
、useNavigate
、fetcher.submit
、fetcher.load
) 帶來了新的 unstable_flushSync
選項,讓使用者可以選擇加入同步 DOM 更新,用於處理中/樂觀 UI。
function handleClick() {
submit(data, { flushSync: true });
// Everything is flushed to the DOM so you can focus/scroll to your pending/optimistic UI
setFocusAndOrScrollToNewlyAddedThing();
}
unstable_flushSync
選項至 useNavigate
/useSubmit
/fetcher.load
/fetcher.submit
,以便選擇退出 React.startTransition
並改用 ReactDOM.flushSync
進行狀態更新 (#11005)useBlocker
Hook 的 unstable_
前綴,因為此 Hook 已使用足夠長時間,我們對其 API 感到有信心 (#10991)window.confirm
的方式存在差異,導致 React Router 無法保證一致/正確的行為,因此我們不打算移除 unstable_usePrompt
的前綴修復 useActionData
,使其返回正確的上下文動作資料,而非樹狀結構中的任何動作資料 (#11023)
修復 useResolvedPath
中的錯誤,該錯誤會導致 splat 路由中的 useResolvedPath(".")
遺失 URL 路徑的 splat 部分。 (#10983)
"."
路徑,該路徑會錯誤地捨棄 URL 的 splat 部分。如果您在應用程式的 splat 路由內透過 "."
進行相對路由,則應仔細檢查您的邏輯是否依賴此錯誤行為,並相應地更新。修復了在 useFetcher
中,已掛載但變更的 fetcher key
未被偵測到的問題 (#11009)
修復了 useFormAction
,它會錯誤地從子路由 action
提交繼承 ?index
查詢參數 (#11025)
修復 NavLink
active
邏輯,當 to
位置具有尾部斜線時 (#10734)
修復類型,使 unstable_usePrompt
除了 boolean
外,還可以接受 BlockerFunction
(#10991)
修復 relative="path"
錯誤,其中相對路徑計算從完整位置路徑名稱開始,而非從目前的上下文路由路徑名稱開始。 (#11006)
<Route path="/a">
<Route path="/b" element={<Component />}>
<Route path="/c" />
</Route>
</Route>;
function Component() {
return (
<>
{/* This is now correctly relative to /a/b, not /a/b/c */}
<Link to=".." relative="path" />
<Outlet />
</>
);
}
完整變更日誌:6.18.0...6.19.0
日期:2023-10-31
根據此 RFC,我們引入了一些新的 API,讓您可以更精細地控制 fetcher 行為。
useFetcher({ key: string })
指定自己的 fetcher 識別符,這讓您可以從應用程式中的不同元件存取相同的 fetcher 實例,而無需逐層傳遞 propsuseFetchers
返回的 fetcher 上,以便可以透過 key
查找Form
和 useSubmit
現在支援可選的 navigate
/fetcherKey
props/參數,以允許在底層啟動 fetcher 提交,並可選擇使用者指定的 key
<Form method="post" navigate={false} fetcherKey="my-key">
submit(data, { method: "post", navigate: false, fetcherKey: "my-key" })
useFetchers()
或 useFetcher({ key })
在其他地方查找future.v7_fetcherPersist
)根據與上述相同的 RFC,我們引入了一個新的 future.v7_fetcherPersist
標誌,讓您可以選擇加入新的 fetcher 持久性/清除行為。Fetcher 不會在卸載時立即清除,而是會持續存在,直到它們返回 idle
狀態。這使得在原始 fetcher 需要卸載的情況下,待處理/樂觀 UI更加容易。
useFetchers()
API 始終應該只反映待處理/樂觀 UI 的正在進行中的 fetcher 資訊 -- 它並非旨在反映 fetcher 資料或在 fetcher 返回 idle
狀態後保留 fetcheruseFetchers()
中 - 它們在那裡沒有任何用途,因為您可以透過 useFetcher().data
存取資料idle
狀態後清除useFetchers
公開,因此您仍然可以在卸載後存取待處理/樂觀資料key
重新掛載 fetcher,則即使原始 fetcher 已卸載,其結果也將被處理key
API 和 navigate=false
選項 (#10960)future.v7_fetcherPersist
標誌 (#10962)matchPath
中新增對可選路徑段的支援 (#10768)BrowserRouter
、HashRouter
和 MemoryRouter
上的 future
prop,使其接受 Partial<FutureConfig>
,而不是要求包含所有標誌 (#10962)router.getFetcher
/router.deleteFetcher
類型定義,它們錯誤地將 key
指定為可選參數 (#10960)完整變更日誌:6.17.0...6.18.0
日期:2023-10-16
我們很高興在 React Router 中發布對 View Transitions API 的實驗性支援!您現在可以觸發導航 DOM 更新,使其包裝在 document.startViewTransition
中,以在應用程式中的 SPA 導航上啟用 CSS 動畫轉場效果。
在 React Router 應用程式中啟用 View Transition 的最簡單方法是透過新的 <Link unstable_viewTransition>
prop。這將導致導航 DOM 更新包裝在 document.startViewTransition
中,這將為 DOM 更新啟用轉場效果。在沒有任何額外 CSS 樣式的情況下,您將獲得頁面的基本交叉淡入淡出動畫。
如果您需要為動畫應用更精細的樣式,則可以利用 unstable_useViewTransitionState
Hook,它會告訴您轉場何時正在進行中,您可以使用它來應用類別或樣式
function ImageLink(to, src, alt) {
const isTransitioning = unstable_useViewTransitionState(to);
return (
<Link to={to} unstable_viewTransition>
<img
src={src}
alt={alt}
style={{
viewTransitionName: isTransitioning ? "image-expand" : "",
}}
/>
</Link>
);
}
您也可以使用 <NavLink unstable_viewTransition>
簡寫,它將為您管理 Hook 的使用,並在轉場期間自動將 transitioning
類別新增至 <a>
a.transitioning img {
view-transition-name: "image-expand";
}
<NavLink to={to} unstable_viewTransition>
<img src={src} alt={alt} />
</NavLink>
有關 View Transitions 的範例用法,請查看 我們的 fork,這是對出色的 Astro Records 示範的 fork。
有關使用 View Transitions API 的更多資訊,請參閱 Google Chrome 團隊的 使用 View Transitions API 實現流暢且簡單的轉場效果 指南。
sessionStorage
不可用時,在 ScrollRestoration
中記錄警告並優雅地失敗 (#10848)RouterProvider
future
prop 類型為 Partial<FutureConfig>
,以便不必指定所有標誌 (#10900)ErrorResponse
類型以避免洩露內部欄位 (#10876)完整變更日誌:6.16.0...6.17.0
日期:2023-09-13
any
的用法替換為 unknown
,用於使用者提供的資料。為了在 Remix v2 中執行此操作,而不會在 React Router v6 中引入破壞性變更,我們已將泛型新增至許多共用類型。這些在 React Router 中繼續預設為 any
,並在 Remix 中被覆寫為 unknown
。在 React Router v7 中,我們計劃將這些變更為 unknown
,作為破壞性變更。 (#10843)Location
現在接受 location.state
值的泛型ActionFunctionArgs
/ActionFunction
/LoaderFunctionArgs
/LoaderFunction
現在接受 context
參數的泛型 (僅在透過 createStaticHandler
的 SSR 用法中使用)useMatches
的返回類型 (現在導出為 UIMatch
) 接受 match.data
和 match.handle
的泛型 - 這兩者都已設定為 unknown
@private
類別導出 ErrorResponse
移動到 UNSAFE_ErrorResponseImpl
導出,因為它是實作細節,並且使用者端程式碼中不應建構 ErrorResponse
實例。這讓我們可以自由導出 type ErrorResponse
,它透過 InstanceType
與類別的實例相關聯。使用者端程式碼應始終僅將 ErrorResponse
用作類型,並且應透過 isRouteErrorResponse
進行類型縮小。 (#10811)ShouldRevalidateFunctionArgs
介面 (#10797)_isFetchActionRedirect
、_hasFetcherDoneAnything
) (#10715)query
/queryRoute
呼叫的錯誤訊息中新增 method/url (#10793)route.lazy
路由上 loader/action 拋出的錯誤的競爭條件 (#10778)shouldRevalidate
的 arguments 物件上的 actionResult
類型 (#10779)完整變更日誌:v6.15.0...v6.16.0
日期:2023-08-10
redirectDocument()
函數,讓使用者可以指定來自 loader
/action
的重新導向應觸發文件重新載入 (透過 window.location
),而不是嘗試透過 React Router 導航到重新導向的位置 (#10705)useRevalidator
在重新渲染之間保持引用穩定,如果重新驗證未主動發生 (#10707)URLSearchParams
和 useSearchParams
Hook 的 Web 擴充功能的邊緣案例 (#10620)unstable_usePrompt
中的 effects,以避免在 prompt 被解除封鎖且同步執行導航時拋出例外 (#10687, #10718)useFormAction()
中包含 hash,因為它無法在伺服器上確定,並且會導致 hydration 問題 (#10758)queryRoute
中的問題,該問題並非始終識別拋出的 Response
實例 (#10717)react-router-native
:將 @ungap/url-search-params
依賴項從 ^0.1.4
更新到 ^0.2.2
(#10590)完整變更日誌:v6.14.2...v6.15.0
日期:2023-07-17
<Form state>
prop,以在提交導航時填充 history.state
(#10630)defer
promise 解析/拒絕 undefined
,則觸發錯誤,以便與 loader 和 action 的行為相符,後者必須返回一個值或 null
(#10690)<ScrollRestoration>
模擬 hash 滾動時,正確解碼元素 id (#10682)Route.lazy
的返回類型,以禁止返回空物件 (#10634)Error
子類別,例如 ReferenceError
/TypeError
(#10633)完整變更日誌:v6.14.1...v6.14.2
日期:2023-06-30
unstable_useBlocker
中的迴圈 (#10652)@remix-run/router@1.7.1
完整變更日誌:v6.14.0...v6.14.1
日期:2023-06-23
6.14.0
新增了透過 useSubmit
/fetcher.submit
支援 JSON 和 Text 提交,因為如果您在用戶端 SPA 中工作,則必須序列化為 FormData
並非總是方便。若要選擇加入這些編碼,您只需要指定正確的 formEncType
選擇加入 application/json
編碼
function Component() {
let navigation = useNavigation();
let submit = useSubmit();
submit({ key: "value" }, { method: "post", encType: "application/json" });
// navigation.formEncType => "application/json"
// navigation.json => { key: "value" }
}
async function action({ request }) {
// request.headers.get("Content-Type") => "application/json"
// await request.json() => { key: "value" }
}
選擇加入 text/plain
編碼
function Component() {
let navigation = useNavigation();
let submit = useSubmit();
submit("Text submission", { method: "post", encType: "text/plain" });
// navigation.formEncType => "text/plain"
// navigation.text => "Text submission"
}
async function action({ request }) {
// request.headers.get("Content-Type") => "text/plain"
// await request.text() => "Text submission"
}
⚠️ v7 中的預設行為將會變更
請注意,為了避免破壞性變更,預設行為仍會將簡單的 key/value JSON 物件編碼為 FormData
實例
function Component() {
let navigation = useNavigation();
let submit = useSubmit();
submit({ key: "value" }, { method: "post" });
// navigation.formEncType => "application/x-www-form-urlencoded"
// navigation.formData => FormData instance
}
async function action({ request }) {
// request.headers.get("Content-Type") => "application/x-www-form-urlencoded"
// await request.formData() => FormData instance
}
此行為可能會在 v7 中變更,因此最好使用 formEncType: "application/x-www-form-urlencoded"
或 formEncType: "application/json"
明確化任何 JSON 物件提交,以簡化您最終的 v7 遷移路徑。
useSubmit
/fetcher.submit
的 application/json
和 text/plain
編碼的支援。為了反映這些額外類型,useNavigation
/useFetcher
現在也包含 navigation.json
/navigation.text
和 fetcher.json
/fetcher.text
,它們包含 json/text 提交 (如果適用)。 (#10413)submitter
元素提交表單時,優先使用內建的 new FormData(form, submitter)
,而不是先前在現代瀏覽器中的手動方法 (那些支援新的 submitter
參數的瀏覽器) (#9865)type="image"
按鈕的基本支援formdata-submitter-polyfill
window.history.pushState/replaceState
,以便在同步 React 17 渲染期間,window.location
與 useLocation
相符 (#10448)window.location
,而應盡可能參考 useLocation
,因為 window.location
並非 100% 時間都同步 (由於 popstate
事件、並行模式等)shouldRevalidate
(#10623)<ScrollRestoration getKey>
的 location
中剝離 basename
,以符合 useLocation
行為 (#10550)unstable_useBlocker
函數的位置中剝離 basename
,以符合 useLocation
行為 (#10573)StrictMode
中的 unstable_useBlocker
金鑰問題 (#10573)0
值參數時的 generatePath
(#10612)tsc --skipLibCheck:false
問題 (#10622)typescript
升級到 5.1 (#10581)完整變更日誌:v6.13.0...v6.14.0
日期:2023-06-14
6.13.0
實際上是一個修補程式版本,但由於我們新增了一個新的未來標誌,因此帶有 SemVer 次要版本升級。
future.v7_startTransition
簡而言之; 6.13.0
與 6.12.0
相同,但我們已將 React.startTransition
的用法移至選擇加入的 future.v7_startTransition
未來標誌 後面,因為我們發現在野外有些應用程式目前以與 React.startTransition
不相容的方式使用 Suspense
。
因此,在 6.13.0
中,預設行為將不再利用 React.startTransition
<BrowserRouter>
<Routes>{/*...*/}</Routes>
</BrowserRouter>
<RouterProvider router={router} />
如果您希望啟用 React.startTransition
,請將未來標誌傳遞給您的路由器元件
<BrowserRouter future={{ v7_startTransition: true }}>
<Routes>{/*...*/}</Routes>
</BrowserRouter>
<RouterProvider router={router} future={{ v7_startTransition: true }}/>
我們建議大家盡早採用此標誌,以便更好地與 React 並行模式相容,但如果您遇到問題,則可以在沒有使用 React.startTransition
的情況下繼續使用,直到 v7。問題通常歸結為在渲染週期期間建立全新的 promise,因此如果您在選擇加入 React.startTransition
時遇到問題,則應將 promise 建立移出渲染週期,或將其放在 useMemo
後面。
React.startTransition
用法移至未來標誌後面 (#10596)React.startTransition
最小化錯誤 (#10588)完整變更日誌:v6.12.1...v6.13.0
日期:2023-06-08
[!WARNING] 請使用
6.13.0
或更新版本,而非6.12.0
/6.12.1
。這些版本受到一些 Webpack 建置/最小化問題的影響,導致生產套件中建置失敗或最小化程式碼無效。詳情請參閱 #10569 和 #10579。
React.startTransition
的功能偵測,以修復 webpack + react 17 編譯錯誤 (#10569)完整變更日誌:v6.12.0...v6.12.1
日期:2023-06-06
[!WARNING] 請使用
6.13.0
或更新版本,而非6.12.0
/6.12.1
。這些版本受到一些 Webpack 建置/最小化問題的影響,導致生產套件中建置失敗或最小化程式碼無效。詳情請參閱 #10569 和 #10579。
React.startTransition
支援在 6.12.0
中,我們透過將內部路由器狀態更新包裝在 React.startTransition
中,新增了對暫停元件的更好支援。這表示,例如,如果您目的地路由中的其中一個元件暫停,並且您沒有提供 Suspense
邊界來顯示後備內容,則 React 將延遲新 UI 的渲染,並顯示舊 UI,直到該非同步操作解析。這對於等待諸如等待圖片或 CSS 檔案載入之類的事情可能很有用 (而且從技術上講,是的,您可以將其用於資料載入,但我們仍然建議使用 loaders 😀)。如需此用法的快速概述,請查看 Ryan 在 Twitter 上的示範。
React.startTransition
包裝內部路由器狀態更新 (#10438)PUSH
導航時,重新拋出 DOMException
(DataCloneError
)。 (#10427)jest
和 jsdom
(#10453)@remix-run/router@1.6.3
(變更日誌)完整變更日誌:v6.11.2...v6.12.0
日期:2023-05-17
<RouterProvider>
內後代 <Routes>
中的 basename
重複問題 (#10492)SetURLSearchParams
類型 (#10444)_internalSetRoutes
中正確重建新路由和 manifest
,修復 Remix HMR 驅動的錯誤邊界 (#10437)完整變更日誌:v6.11.1...v6.11.2
日期:2023-05-03
<Routes>
中 Component
API 的用法 (#10434)<RouterProvider>
內部的 <Routes>
呼叫 useNavigate
時的錯誤 (#10432)<Navigate>
(#10435)basename
處理 (#10433)/path#hash -> /path#hash
) (#10408)完整變更日誌:v6.11.0...v6.11.1
日期:2023-04-28
useFetcher
中啟用 basename
支援 (#10336)basename
來解決此問題,則需要從您的 fetcher
呼叫中移除手動預先準備的 basename
(fetcher.load('/basename/route') -> fetcher.load('/route')
)@remix-run/router@1.6.0
(變更日誌)RouterProvider
時,useNavigate
/useSubmit
/fetcher.submit
現在在位置變更時保持穩定,因為我們可以透過 @remix-run/router
實例處理相對路由,並擺脫我們對 useLocation()
的依賴 (#10336)BrowserRouter
時,這些 Hook 在位置變更時仍保持不穩定,因為它們仍然依賴 useLocation()
action
提交或 router.revalidate
呼叫時重新驗證 ( #10344 )Component
而非 element
時,發生的意外重新渲染問題 ( #10287 )<Link to="//">
和其他無效 URL 值,優雅地處理失敗情況 ( #10367 )<RouterProvider>
中,將內部 @remix-run/router
router 狀態同步從 useSyncExternalStore
切換到 useState
。我們發現一些 細微的錯誤 ,其中 router 狀態更新在其他正常的 useState
更新之前傳播,這可能會導致 useEffect
呼叫中出現隱藏的錯誤。( #10377 , #10409 )RouterProvider
存在錯誤時,阻止渲染後代 <Routes>
的錯誤 ( #10374 )activeRef
,修正渲染週期中 useNavigate
的偵測問題,允許將 navigate
函數傳遞給子元件並在那裡的 useEffect
中呼叫 ( #10394 )useRevalidator()
解決 loader 驅動的錯誤邊界情境 ( #10369 )LoaderFunction
/ActionFunction
返回類型,以防止 undefined
成為有效的返回值 ( #10267 )loader
的路由進行 fetcher.load
呼叫時,出現正確的 404 錯誤 ( #10345 )AbortController
用法解耦,這樣重新驗證 fetcher 的卸載/刪除不會影響正在進行的觸發導航/重新驗證 ( #10271 )完整變更日誌: v6.10.0...v6.11.0
日期:2023-03-29
我們最近在 Remix 部落格上發表了一篇文章,標題為 "讓你的 Remix 應用程式面向未來",其中介紹了我們的策略,以確保你的 Remix 和 React Router 應用程式未來能夠順利升級。React Router 6.10.0
新增了對這些標誌 (針對資料路由器) 的支援,你可以在建立路由器時指定這些標誌
const router = createBrowserRouter(routes, {
future: {
// specify future flags here
},
});
future.v7_normalizeFormMethod
引入的第一個未來標誌是 future.v7_normalizeFormMethod
,它將標準化公開的 useNavigation()/useFetcher()
formMethod
欄位,使其成為大寫 HTTP 方法,以符合 fetch()
(和一些 Remix) 的行為。( #10207 )
future.v7_normalizeFormMethod
未指定或設定為 false
(預設 v6 行為) 時,useNavigation().formMethod
是小寫useFetcher().formMethod
是小寫future.v7_normalizeFormMethod === true
時useNavigation().formMethod
是大寫useFetcher().formMethod
是大寫createStaticHandler
,使其在路由上也檢查 ErrorBoundary
以及 errorElement
( #10190 )createRoutesFromElements
中使用 Fragments 時的路由 ID 生成問題 ( #10193 )shouldRevalidate
( #10208 )lazy()
錯誤 ( #10201 )instanceof
對 DeferredData
的檢查,以在 SSR 捆綁情境中對 ESM/CJS 邊界具有彈性 ( #10247 )@remix-run/web-fetch@4.3.3
( #10216 )完整變更日誌: v6.9.0...v6.10.0
日期:2023-03-10
Component
/ErrorBoundary
路由屬性React Router 現在支援另一種方式來將你的路由 element
和 errorElement
欄位定義為 React 元件,而不是 React 元素。你可以選擇將 React 元件傳遞給新的 Component
和 ErrorBoundary
欄位。兩者之間沒有功能上的差異,因此請使用你喜歡的方法 😀。你不應該同時定義兩者,但如果你這樣做,Component
/ErrorBoundary
將會「勝出」
JSON 語法範例
// Both of these work the same:
const elementRoutes = [{
path: '/',
element: <Home />,
errorElement: <HomeError />,
}]
const componentRoutes = [{
path: '/',
Component: Home,
ErrorBoundary: HomeError,
}]
function Home() { ... }
function HomeError() { ... }
JSX 語法範例
// Both of these work the same:
const elementRoutes = createRoutesFromElements(
<Route path='/' element={<Home />} errorElement={<HomeError /> } />
);
const componentRoutes = createRoutesFromElements(
<Route path='/' Component={Home} ErrorBoundary={HomeError} />
);
function Home() { ... }
function HomeError() { ... }
為了保持你的應用程式捆綁包小巧並支援路由的程式碼分割,我們引入了一個新的 lazy()
路由屬性。這是一個異步函數,它解析你的路由定義中非路由匹配的部分 (loader
、action
、element
/Component
、errorElement
/ErrorBoundary
、shouldRevalidate
、handle
)。
Lazy 路由會在初始載入以及導航或 fetcher 呼叫的 loading
或 submitting
階段解析。你無法延遲定義路由匹配屬性 (path
、index
、children
),因為我們僅在匹配已知路由後才執行你的 lazy 路由函數。
你的 lazy
函數通常會返回動態 import 的結果。
// In this example, we assume most folks land on the homepage so we include that
// in our critical-path bundle, but then we lazily load modules for /a and /b so
// they don't load until the user navigates to those routes
let routes = createRoutesFromElements(
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="a" lazy={() => import("./a")} />
<Route path="b" lazy={() => import("./b")} />
</Route>
);
然後在你的 lazy 路由模組中,匯出你想要為路由定義的屬性
export async function loader({ request }) {
let data = await fetchData(request);
return json(data);
}
// Export a `Component` directly instead of needing to create a React Element from it
export function Component() {
let data = useLoaderData();
return (
<>
<h1>You made it!</h1>
<p>{data}</p>
</>
);
}
// Export an `ErrorBoundary` directly instead of needing to create a React Element from it
export function ErrorBoundary() {
let error = useRouteError();
return isRouteErrorResponse(error) ? (
<h1>
{error.status} {error.statusText}
</h1>
) : (
<h1>{error.message || error}</h1>
);
}
可以在儲存庫的 examples/lazy-loading-router-provider
目錄中找到此操作的範例。有關更多資訊,請查看 lazy
文檔。
🙌 非常感謝 @rossipedia 的 初始提案 和 POC 實作。
generatePath
在某些情況下錯誤地應用參數的問題 ( #10078 )[react-router-dom-v5-compat]
新增遺漏的資料路由器 API 重新匯出 ( #10171 )完整變更日誌: v6.8.2...v6.9.0
日期:2023-02-27
<Link to>
中的同源絕對 URL 超出路由器 basename
範圍,則將其視為外部連結 ( #10135 )basename
範圍的同源絕對 URL,正確執行硬重新導向 ( #10076 )<Link to>
url 的 SSR 問題 ( #10112 )StaticRouterProvider
序列化 hydration 資料中正確轉義 HTML 字元 ( #10068 )useBlocker
返回 IDLE_BLOCKER
的問題 ( #10046 )createStaticHandler
的 query()
方法中,為 defer
loader 響應維護狀態碼和標頭 ( #10077 )invariant
變更為 UNSAFE_invariant
匯出,因為它僅供內部使用 ( #10066 )完整變更日誌: v6.8.1...v6.8.2
日期:2023-02-06
Link
元件中的絕對 url 偵測 (現在也支援 mailto:
urls) ( #9994 )完整變更日誌: v6.8.0...v6.8.1
日期:2023-01-26
支援 <Link to>
中的絕對 URL。如果 URL 指向當前 origin,它仍然會執行客戶端導航。如果 URL 指向不同的 origin,那麼它將為新的 origin 執行全新的文檔請求。( #9900 )
<Link to="https://neworigin.com/some/path"> {/* Document request */}
<Link to="//neworigin.com/some/path"> {/* Document request */}
<Link to="https://www.currentorigin.com/path"> {/* Client-side navigation */}
shouldRevalidate
呼叫的 2 個獨立問題 ( #9948 )shouldRevalidate
函數僅針對顯式重新驗證情境 (在變更、手動 useRevalidator
呼叫或用於在 Remix 中設定 Cookie 的 X-Remix-Revalidate
標頭之後) 呼叫。它沒有在也適用於導航 loader
重新驗證的隱式重新驗證情境中正確呼叫,例如搜尋參數的變更或點擊我們已在頁面上的連結。現在在這些額外的情境中已正確呼叫。current*
/next*
參數反映了靜態 fetcher.load
URL (因此是相同的)。相反,它們應該反映觸發重新驗證的導航 (如 form*
參數所做的那樣)。這些參數現在正確地反映了觸發導航。useSearchParams
移除搜尋參數的錯誤 ( #9969 )<fetcher.Form>
上的 preventScrollReset
( #9963 )<ScrollRestoration>
使用 pagehide
而不是 beforeunload
。這具有更好的跨瀏覽器支援,特別是在 Mobile Safari 上。( #9945 )isRouteErrorResponse
移除 instanceof
檢查,以避免伺服器上的捆綁問題 ( #9930 )defer
呼叫何時僅包含重要資料,並移除 AbortController
( #9965 )File
FormData
條目時,將名稱作為值發送 ( #9867 )react-router-dom-v5-compat
- 修正在使用 CompatRouter
時的 SSR useLayoutEffect
console.error
問題 ( #9820 )完整變更日誌: v6.7.0...v6.8.0
日期:2023-01-18
unstable_useBlocker
/unstable_usePrompt
Hook,用於阻止應用程式位置 origin 內的導航 ( #9709 , #9932 )preventScrollReset
prop 新增到 <Form>
( #9886 )useBeforeUnload
( #9709 )generatePath
在可選參數存在時的問題 ( #9764 )<Await>
以接受 ReactNode
作為子函數返回結果 ( #9896 )jsdom
錯誤修復 ( #9824 )完整變更日誌: v6.6.2...v6.7.0
日期:2023-01-09
useId
的一致性 ( #9805 )完整變更日誌: v6.6.1...v6.6.2
日期:2022-12-23
shouldRevalidate
中 ( #9777 , #9782 )actionData
( #9772 )完整變更日誌: v6.6.0...v6.6.1
日期:2022-12-21
此小版本主要用於穩定我們資料路由器的 SSR API,現在我們已在 Remix 中連接了新的 RouterProvider
,作為 React Router-ing Remix 工作的一部分。
createStaticHandler
/createStaticRouter
/StaticRouterProvider
移除 unstable_
前綴 ( #9738 )useBeforeUnload()
Hook ( #9664 )<Form method>
和 useSubmit
方法值 ( #9664 )<button formmethod>
表單提交覆蓋問題 ( #9664 )replace
和提交到新路徑時的 PUSH
問題 ( #9734 )errorElement
中使用 useLoaderData
( #9735 )StaticRouterProvider
的 Error
物件 ( #9664 )hydrationData
的 SSR 應用程式的初始滾動恢復 ( #9664 )完整變更日誌: v6.5.0...v6.6.0
日期:2022-12-16
此版本引入了對 可選路由段 的支援。現在,在任何路徑段的末尾新增 ?
將使整個段成為可選的。這適用於靜態段和動態參數。
可選參數範例
<Route path=":lang?/about>
將匹配/:lang/about
/about
<Route path="/multistep/:widget1?/widget2?/widget3?">
將匹配/multistep
/multistep/:widget1
/multistep/:widget1/:widget2
/multistep/:widget1/:widget2/:widget3
可選靜態段範例
<Route path="/home?">
將匹配/
/home
<Route path="/fr?/about">
將匹配/about
/fr/about
<Route path="prefix-:param">
,以與 splat 參數的工作方式對齊。如果你之前依賴此行為,則建議在 useParams
呼叫站點提取路徑的靜態部分:( #9506 )// Old behavior at URL /prefix-123
<Route path="prefix-:id" element={<Comp /> }>
function Comp() {
let params = useParams(); // { id: '123' }
let id = params.id; // "123"
...
}
// New behavior at URL /prefix-123
<Route path=":id" element={<Comp /> }>
function Comp() {
let params = useParams(); // { id: 'prefix-123' }
let id = params.id.replace(/^prefix-/, ''); // "123"
...
}
action
請求後,持久化 loader
request
的 headers
( #9721 )完整變更日誌: v6.4.5...v6.5.0
日期:2022-12-07
GET
請求 ( #9680 )instanceof Response
檢查,改用 isResponse
( #9690 )URL
建立問題 ( #9682 , #9689 )requestContext
支援到靜態處理器 query
/queryRoute
( #9696 )queryRoute(path, routeId)
的不穩定 API 已變更為 queryRoute(path, { routeId, requestContext })
完整變更日誌: v6.4.4...v6.4.5
日期:2022-11-30
action
/loader
函數返回 undefined
,則拋出錯誤,因為重新驗證需要知道 loader 之前是否已執行過。undefined
也會在 SSR 字串化以進行 hydration 時引起問題。你應始終確保你的 loader
/action
返回一個值,如果你不希望返回任何內容,則可以返回 null
。( #9511 )basename
( #9591 )ErrorResponse
主體在內部 403/404/405 情境中包含更多描述性文字NavLink
和後代 <Routes>
中編碼字元的問題 ( #9589 , #9647 )ErrorResponse
實例 ( #9593 )basename
( #9591 )@remix-run/router@1.0.4
react-router@6.4.4
完整變更日誌: v6.4.3...v6.4.4
日期:2022-11-01
createHashRouter
時,產生正確的 <a href>
值 ( #9409 )index
路由也具有 path
時,產生正確的 formAction
路徑名稱 ( #9486 )NavLink
上的 relative=path
prop ( #9453 )NavLink
行為 ( #9497 )locationArg
時,useRoutes
應該能夠返回 null
( #9485 )createMemoryRouter
中的 initialEntries
類型 ( #9498 )loader
/action
重新導向中的 basename
和相對路由 ( #9447 )action
函數時,忽略無路徑佈局路由 ( #9455 )@remix-run/router
新增 UMD 建置 ( #9446 )createURL
問題 ( #9464 )完整變更日誌: v6.4.2...v6.4.3
日期:2022-10-06
useFormAction
中的 basename
( #9352 )IndexRouteObject
和 NonIndexRouteObject
類型,使 hasErrorElement
成為可選 ( #9394 )RouteObject
/RouteProps
類型,以在 TypeScript 中顯示錯誤。( #9366 )完整變更日誌: v6.4.1...v6.4.2
日期:2022-09-22
完整變更日誌: v6.4.0...v6.4.1
日期:2022-09-13
哇,這是一個大版本!6.4.0
將所有資料載入和變更 API 從 Remix 移植過來。以下是一個快速的高級概述,但建議你查看 文檔,尤其是 功能概述 和 教程。
新的 react-router
API
createMemoryRouter
建立你的路由器<RouterProvider>
渲染你的路由器loader
載入資料,並使用路由 action
變更資料errorElement
處理錯誤defer
和 Await
延遲非關鍵資料新的 react-router-dom
API
createBrowserRouter
/createHashRouter
建立你的路由器<Form>
元件提交資料useFetcher()
執行頁內資料載入和變更defer
和 Await
延遲非關鍵資料<ScrollRestoration>
管理滾動位置<Link relative="path">
執行路徑相對導航 ( #9160 )useLocation
返回 <Routes location>
元件內的作用域位置 ( #9094 )<Link replace>
prop,則尊重它 ( #8779 )完整變更日誌: v6.3.0...v6.4.0
日期:2022-03-31
完整變更日誌: v6.2.2...v6.3.0
日期:2022-02-28
完整變更日誌: v6.2.1...v6.2.2
日期:2021-12-17
history
依賴項更新為 5.2.0
。完整變更日誌: v6.2.0...v6.2.1
日期:2021-12-17
完整變更日誌: v6.1.1...v6.2.0
日期:2021-12-11
HistoryRouter
標記為 unstable_HistoryRouter
,因為此 API 可能需要在新的主要版本發布之前進行更改。完整變更日誌: v6.1.0...v6.1.1
日期:2021-12-10
<Outlet>
現在可以接收 context
屬性。此值會傳遞給子路由,並且可以通過新的 useOutletContext
Hook 存取。請參閱 API 文件 以了解詳細資訊。 (#8461)<NavLink>
現在可以接收子函數以存取其屬性。 (#8164)useMatch
和 matchPath
的 TypeScript 簽名。例如,當您呼叫 useMatch("foo/:bar/:baz")
時,路徑會被解析,並且返回類型將為 PathMatch<"bar" | "baz">
。 (#8030)完整變更日誌: v6.0.2...v6.1.0
日期:2021-11-09
<Link>
添加了 reloadDocument
屬性。這允許 <Link>
像普通的錨點標籤一樣運作,方法是在導航後重新載入文檔,同時保持相對的 to
解析度 (#8283)完整變更日誌: v6.0.1...v6.0.2
日期:2021-11-05
完整變更日誌: v6.0.0...v6.0.1
日期:2021-11-03
React Router v6 登場!
請閱讀我們的部落格文章,以深入了解 v6 的所有精彩功能,包括關於 如何從 React Router v5 和 Reach Router 升級的說明。