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!
此版本增強了使用預先渲染路徑與其他在 ssr:false
預先渲染時以「SPA 模式」運作的路徑組合的能力。
prerender
設定的 ssr:false
,則這會被視為「SPA 模式」,而產生的 index.html
檔案只會渲染到根路由,並且能夠為任何有效的應用程式路徑進行水合prerender
設定但不包含 /
路徑 (即 prerender: ['/blog/post']
) 的 ssr:false
,那麼我們仍然會產生一個「SPA 模式」index.html
檔案,該檔案可以為應用程式中的任何路徑進行水合ssr:false
並在您的 prerender
設定中包含 /
路徑,則產生的 index.html
檔案將特定於根索引路由,因此我們現在也會在 __spa-fallback.html
中產生一個單獨的「SPA 模式」檔案,您可以為非預先渲染的路徑提供服務/水合如需更多資訊,請參閱 預先渲染 文件以取得更多資訊。
loader
SPA 模式過去禁止在所有路由中使用載入器,以便我們可以為應用程式中的任何路徑進行水合。但是,由於根路由總是在建置時渲染,因此我們可以解除對根路由的此限制。
為了在預先渲染期間使用您的建置時載入器資料,我們現在也將 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
的伺服器載入器,我們會短路並跳過單一擷取 .data
請求邏輯.data
請求react-router
- 當設定 ssr:false
時,使開發伺服器行為與靜態檔案伺服器行為對齊 (#12948)prerender
設定時,僅 SSR 下降到根 HydrateFallback
(SPA 模式)prerender
設定但目前路徑未預先渲染時,僅 SSR 下降到根 HydrateFallback
(SPA 回退).data
請求中傳回 404react-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)ssr:false
路由中使用 headers
/action
函式,因為將沒有執行階段伺服器來執行它們loader
函式更細緻,並且取決於給定路由是否預先渲染prerender
設定的 ssr:false
時,只有 root
路由可以有 loader
prerender
設定的 ssr:false
時,只有與 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 路由內部的雜湊路由時出現問題 (#12927)完整更新日誌: v7.1.4...v7.1.5
日期:2025-01-30
@react-router/dev
- 在使用 unstable_optimizeDeps
未來標誌時,正確解析 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
- 修正 fetcher 取消掛載時,資料層中 fetcher 資料清理的問題 (#12681)react-router
- 請勿依賴 symbol
從載入器資料中篩選出 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/data 檔案時,路徑缺少前導斜線的錯誤 (#12684)@react-router/dev
- 在運行時啟用時,使用 module-sync
伺服器條件。這修正了在 Node 22.10.0+ 上開發期間,當使用對 React Router 有同層級依賴的函式庫時,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 具有同層級依賴 (#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
引數。如果需要,您仍然可以將建置資訊清單寫入磁碟,但您很可能會發現將任何依賴於建置資訊清單的邏輯寫入 buildEnd
hook 本身更方便。(<#11573)
如果您正在使用 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 將在一級支援在渲染過程中處理 promises (透過 React.use
和 useAction
),我們現在很放心地公開先前返回 undefined
的 API 的 promises
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
的原始 promises (#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
-> 以 NavigationType
透過 react-router
匯出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
react-router
中,因此整合先前在 @remix-run/router
、@remix-run/server-runtime
和 @remix-run/react
中重複的類型 (#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 消費者,@react-router/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 資訊清單 (即 .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 資訊清單檔案,除非在應用程式的 Vite 組態中啟用了 Vite 的 build.manifest
。這大大降低了在生產環境中意外提供 Vite 資訊清單的風險,因為它們僅在明確要求時才存在。因此,我們現在可以假設消費者將知道他們需要自己管理這些額外檔案,並且 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 的文件載入時正確還原 (#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
- 修正從使用 data()
的 loaders/actions 返回的 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()
結果時,正確地冒泡標頭 (#12845)matchRoutes
呼叫來最佳化路由匹配 (#12169)patchRoutesOnNavigation
path
參數中移除搜尋參數,用於 fetcher 呼叫 (#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
的進行中呼叫,以便具有相同開始/結束的多個導航只會執行一次函數並使用相同的 Promiserequest.signal
中止),則此方法與 patch
短路相矛盾,因為第一次調用的 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
,以便我們不會在後續導航到相同路徑時重新呼叫完整變更日誌: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
現在將包含任何 partial 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
內的路徑,以便 matches/params 反映解碼後的參數 (#11789)unstable_patchRoutesOnMiss
擲出的錯誤冒泡 (#11786)unstable_patchRoutesOnMiss
的 SSR 應用程式中的 hydration,該應用程式在伺服器上比對了 splat 路由 (#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。簡而言之;自從我們在 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
future 標記 (#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
錯誤,如果 SSR 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
完整變更日誌:v6.21.2...v6.21.3
日期:2024-01-11
完整變更日誌:v6.21.1...v6.21.2
日期:2023-12-21
route.lazy
在指定 v7_partialHydration
時無法在初始 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 標記,該標記在伺服器端渲染時啟用資料路由器的 partial hydration。這允許您提供 hydrationData.loaderData
,其中包含某些初始比對的路由 loader 的值,但並非全部。啟用此標記後,路由器將在 router.initialize()
期間呼叫沒有 hydration loader 資料的路由的 loader
函數,並且它將呈現到最深層提供的 HydrateFallback
(直到第一個沒有 hydration 資料的路由),同時執行未 hydrated 的路由。 (#11033)
future.v7_relativeSplatPath
標記,以實作 splat 路由內相對路由的重大錯誤修正。 (#11087)future.v7_partialHydration
future 標記,該標記在伺服器端渲染時啟用資料路由器的 partial 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
中還原了此修復,並將在後續版本中,於未來標誌後方重新引入。詳情請參閱 #11052。
PathParam
型別 (#10719)v7_fetcherPersist
時,不要重新驗證已卸載的 fetcher (#11044)resolveTo
路徑解析的錯誤 (#11045)getPathContributingMatches
的程式碼路徑react-router
/react-router-dom
層不再需要此功能,因此從 @remix-run/router
中移除 UNSAFE_getPathContributingMatches
匯出完整變更日誌: 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_
前綴,因為此 API 已使用足夠長的時間,我們對其充滿信心 (#10991)window.confirm
的方式存在差異,導致 React Router 無法保證一致/正確的行為,因此我們不打算移除 unstable_usePrompt
的前綴修正 useActionData
,使其傳回適當的上下文 action 資料,而不是樹狀結構中的任何 action 資料 (#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
狀態。這使得待處理/樂觀 UI 在原始 fetcher 需要卸載的情況下更加容易。
useFetchers()
API 應該始終只反映待處理/樂觀 UI 的正在進行中的 fetcher 資訊 - 它不打算反映 fetcher 資料,或在 fetcher 返回到 idle
狀態後繼續保留 fetcheruseFetchers()
中 - 它們在那裡沒有任何作用,因為您可以透過 useFetcher().data
存取資料idle
狀態後清除useFetchers
公開,因此您仍然可以在卸載後存取待處理/樂觀資料key
在樹狀結構中的其他位置重新掛載,則即使原始 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 的範例用法,請查看 我們的分支,這是超棒的 Astro Records 示範。
有關使用 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
呼叫的錯誤訊息中新增方法/URL (#10793)route.lazy
路由上 loader/action 拋出錯誤的競爭條件 (#10778)shouldRevalidate
的參數物件上 actionResult
的型別 (#10779)完整變更日誌: v6.15.0...v6.16.0
日期:2023-08-10
redirectDocument()
函數,允許使用者指定來自 loader
/action
的重新導向應觸發文件重新載入 (透過 window.location
),而不是嘗試透過 React Router 導航到重新導向的位置 (#10705)useRevalidator
在重新渲染時,如果未主動發生重新驗證,則在引用上保持穩定 (#10707)URLSearchParams
和 useSearchParams
Hook 的網頁擴充功能的邊緣案例 (#10620)unstable_usePrompt
中的效果,以避免在 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 的行為一致,loader 和 action 必須傳回值或 null
(#10690)<ScrollRestoration>
模擬 hash 滾動時,正確解碼元素 ID (#10682)Route.lazy
的傳回型別,以禁止傳回空物件 (#10634)Error
子類別 (例如 ReferenceError
/TypeError
) 的正確 hydration (#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 和文字提交,因為如果您在用戶端 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/文字提交。 (#10413)submitter
元素提交表單時,在現代瀏覽器 (那些支援新的 submitter
參數的瀏覽器) 中,優先使用內建的 new FormData(form, 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
key 問題 (#10573)0
值參數時的 generatePath
(#10612)tsc --skipLibCheck:false
問題 (#10622)typescript
升級到 5.1 (#10581)完整變更日誌: v6.13.0...v6.14.0
日期:2023-06-14
6.13.0
實際上是一個修補程式版本,但由於我們新增了一個新的 future 標誌,因此帶有 SemVer 小版本升級。
future.v7_startTransition
重點摘要; 6.13.0
與 6.12.0
相同,但我們已將 React.startTransition
的用法移至選擇加入的 future.v7_startTransition
future 標誌 後方,因為我們發現在實際應用中,有些應用程式目前以與 React.startTransition
不相容的方式使用 Suspense
。
因此,在 6.13.0
中,預設行為將不再利用 React.startTransition
<BrowserRouter>
<Routes>{/*...*/}</Routes>
</BrowserRouter>
<RouterProvider router={router} />
如果您希望啟用 React.startTransition
,請將 future 標誌傳遞給您的路由器組件
<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
用法移至 future 標誌後方 (#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
邊界來顯示 fallback,React 將延遲新 UI 的渲染,並顯示舊 UI,直到該非同步操作解析。這對於等待諸如等待影像或 CSS 檔案載入之類的事情可能很有用 (從技術上講,是的,您可以使用它進行資料載入,但我們仍然建議使用 loader 😀)。有關此用法的快速概觀,請查看 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
路由器狀態同步的機制,從 useSyncExternalStore
切換到 useState
。我們發現一些 細微的錯誤,其中路由器狀態更新在其他正常的 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 博客上發布了一篇名為 "Future Proofing Your Remix App" 的文章,其中介紹了我們確保您的 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
,使其除了 errorElement
之外,還檢查路由上的 ErrorBoundary
(#10190)createRoutesFromElements
中產生路由 ID 時的問題 (#10193)shouldRevalidate
提供 fetcher 提交 (#10208)lazy()
錯誤 (#10201)DeferredData
的 instanceof
檢查,以在 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
函數通常會返回動態導入的結果。
// 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 的 Initial Proposal 和 POC Implementation。
generatePath
在某些情況下錯誤地應用參數的問題 (#10078)[react-router-dom-v5-compat]
新增遺漏的資料路由器 API 重新匯出 (#10171)完整變更日誌:v6.8.2...v6.9.0
日期:2023-02-27
<Link to>
中的同源絕對 URL 超出路由器 basename
,則將其視為外部 URL (#10135)basename
外部的同源絕對 URL 正確執行硬重新導向 (#10076)<Link to>
url 的 SSR 問題 (#10112)StaticRouterProvider
序列化 hydration 資料中的 HTML 字元 (#10068)useBlocker
在 SSR 期間返回 IDLE_BLOCKER
的問題 (#10046)createStaticHandler
的 query()
方法中,為 defer
loader 回應維護狀態代碼和標頭 (#10077)invariant
變更為 UNSAFE_invariant
匯出,因為它僅供內部使用 (#10066)完整變更日誌:v6.8.1...v6.8.2
日期:2023-02-06
Link
組件中的絕對 url 檢測(現在也支援 mailto:
url)(#9994)完整變更日誌:v6.8.0...v6.8.1
日期:2023-01-26
支援 <Link to>
中的絕對 URL。如果 URL 用於當前來源,它仍然會執行客戶端導航。如果 URL 用於不同的來源,則它將為新來源執行全新的文檔請求。( #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
。這具有更好的跨瀏覽器支援,尤其是在行動 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
鉤子,用於阻止應用程式位置來源內的導航 (#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
完整變更日誌:v6.6.0...v6.6.1
日期:2022-12-21
此小版本發布主要是為了穩定我們的 Data Routers SSR API,現在我們已在 Remix 中連接了新的 RouterProvider
,作為 React Router-ing Remix 工作的一部分。
createStaticHandler
/createStaticRouter
/StaticRouterProvider
中移除 unstable_
前綴 (#9738)useBeforeUnload()
鉤子 (#9664)<Form method>
和 useSubmit
方法值 (#9664)<button formmethod>
表單提交覆蓋問題 (#9664)replace
和提交到新路徑時的 PUSH
問題 (#9734)errorElement
中使用 useLoaderData
(#9735)StaticRouterProvider
正確 hydration 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)query
/queryRoute
新增 requestContext
支援 (#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
從 Remix 引入了所有資料載入和變更 API。以下是快速的高階概述,但建議您查看 文檔,尤其是 功能概述 和 教程。
新的 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
prop。此值傳遞給子路由,並且可以通過新的 useOutletContext
鉤子訪問。有關詳細資訊,請參閱 API 文檔。( #8461)<NavLink>
現在可以接收子函數以訪問其 props。( #8164)useMatch
和 matchPath
的 TypeScript 簽名。例如,當您調用 useMatch("foo/:bar/:baz")
時,將解析路徑,並且返回類型將為 PathMatch<"bar" | "baz">
。( #8030)完整變更日誌:v6.0.2...v6.1.0
日期:2021-11-09
reloadDocument
prop 新增至 <Link>
。這允許 <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 升級的注意事項。