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
配置的情况下指定 ssr:false
,但不包含 /
路径(即 prerender: ['/blog/post']
),那么我们仍然会生成一个“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
- 由于没有服务器 HTTP 请求,因此在 SPA 模式下不应用单次 Fetch 重新验证去优化 (#12948)react-router
- 正确处理跨预渲染/SPA 边界的重新验证 (#13021).data
请求,因为该请求将返回 404ssr:false
模式下的所有 loader
数据都是静态的,因为它是在构建时生成的clientLoader
才能执行任何动态操作loader
而没有 clientLoader
,我们默认禁用重新验证,因为没有新数据要检索dataStrategy
中没有 shouldLoad=true
的服务器加载器,我们将短路并跳过单次 Fetch .data
请求逻辑.data
请求react-router
- 当设置 ssr:false
时,使开发服务器行为与静态文件服务器行为对齐 (#12948)prerender
配置时,仅 SSR 到根 HydrateFallback
(SPA 模式)prerender
配置但当前路径未预渲染时,仅 SSR 到根 HydrateFallback
(SPA 回退).data
请求上返回 404react-router
- 提高框架模式下 CSS 副作用的预取性能 (#12889)react-router
- 正确处理懒加载路由发现中中断的清单请求 (#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
- 修复重复参数的 typegen (#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 Environment 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
- 正确处理在单次 Fetch 响应中无法包含主体的状态码(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
不再用于 redirect
响应类型,这些错误应该不再出现@react-router/dev
- 修复 Vite v6 中的默认外部条件 (#12644)@react-router/dev
- 修复当路径缺少前导斜杠时预渲染 html/数据文件不匹配的问题 (#12684)@react-router/dev
- 在运行时启用时使用 module-sync
服务器条件。这修复了 Node 22.10.0+ 上开发期间使用对 React Router 有对等依赖的库时,React 上下文不匹配的问题(例如 useHref() may be used only in the context of a <Router> component.
)。(#12729)@react-router/dev
- 修复 react-refresh
source maps (#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
以与 Single Fetch 之前的行为保持一致 (#12506)react-router
- 在推断加载器数据类型时忽略重定向 (#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 开发服务器重启时清理类型生成文件监视器 (#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 将一流地支持在渲染过程中处理 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 中的包装器 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 的 Remix 用户,他们使用了 Vite 插件的 buildEnd
hook,已解析的 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、加载器数据和 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
添加此项时,它似乎还向 .data
文件添加了 Cache-Control: public, max-age=0
substr
替换为 substring
(#12080)react-router
- 修复从使用 data()
的加载器/action 返回的重定向 (#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
参数中剥离搜索参数 (#12899)完整变更日志: v6.28.2...v6.29.0
日期:2025-01-16
key
用法,当未选择加入 future.v7_fetcherPersist
时 (#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,为 即将到来 的 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_viewTransition
选项和对应的 unstable_useViewTransitionState
hook (#11989)unstable_dataStrategy
(#11974)unstable_patchRoutesOnNavigation
(#11973)PatchRoutesOnNavigationFunctionArgs
类型 (#11967)?index
参数时,提交到当前上下文路由(带有索引子路由的父路由)的 bug (#12003)useFormAction
的 bug - 当移除 ?index
参数时,它不会保留其他非 Remix 的 index
参数 (#12003)preventScrollReset
的 bug (#11999)console.error
(#12050)partialHydration
的 bug (#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
时阻止器的使用问题 (#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
一起使用时的初始水合行为 (#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
内部的路径,以便 matches/params 反映解码后的参数 (#11789)unstable_patchRoutesOnMiss
抛出的错误的冒泡 (#11786)unstable_patchRoutesOnMiss
进行水合时的错误 (#11790)完整更新日志: v6.24.1...v6.25.0
日期: 2024-07-03
polyfill.io
引用,因为该域名已售出,并且此后被确定为提供恶意软件 (#11741)
NavLinkRenderProps
类型,以便更轻松地键入自定义 NavLink
回调 (#11553)future.v7_relativeSplatPath
时,正确解析无路径路由的子路由中 splat 路由中的相对路径 (#11633)router.routes
identity/reflow (#11740)完整更新日志: v6.24.0...v6.24.1
日期: 2024-06-24
我们非常激动地在 v6.24.0
中发布了新的“延迟路由发现”API!有关一些背景信息,请查看原始的 RFC。tl;dr; 是自从我们在 v6.4 中通过 <RouterProvider>
引入 Data 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)location.state
值传递给 <StaticRouter>
(#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
来执行此操作 - 现在 shouldRevalidate
还接收一个新的 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
的一个 bug,该 bug 会在 SSR loader 错误冒泡到父边界时,在水合时重新运行边界下方的 loader (#11324)future.v7_partialHydration
的一个 bug,该 bug 会在路由没有 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
),而不是像 new Error("query() call aborted: GET /path")
这样的 Error
(#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 加载时无法正常工作的 bug (#11121)submitting
阶段卸载的持久化 fetcher 进行重新验证的 bug (#11102)resolveTo
中去重了相对路径逻辑 (#11097)完整更新日志: v6.21.0...v6.21.1
日期: 2023-12-13
future.v7_relativeSplatPath
我们在 6.19.0
中修复了一个 splat 路由路径解析 bug,但后来确定大量应用程序依赖于有 bug 的行为,因此我们在 6.20.1
中恢复了该修复(参见 #10983, #11052, #11078)。
有 bug 的行为是,在 splat 路由内解析相对路径时的默认行为会忽略当前路由路径的任何 splat (*
) 部分。启用 future 标志后,splat 部分将包含在 splat 路由内的相对路径逻辑中。
有关更多信息,请参阅 useResolvedPath
文档 和/或 详细的更新日志条目。
我们为 @remix-run/router
添加了一个新的 future.v7_partialHydration
future 标志,该标志在服务器端渲染时启用数据路由器的部分水合。这允许你提供 hydrationData.loaderData
,其中包含一些初始匹配的路由 loader 的值,但不是全部。启用此标志后,路由器将在 router.initialize()
期间为没有水合 loader 数据的路由调用 loader
函数,并且它将渲染到最深层提供的 HydrateFallback
(直到没有水合数据的第一个路由),同时执行未水合的路由。 (#11033)
future.v7_relativeSplatPath
标志,以实现对 splat 路由内部相对路由的破坏性 bug 修复。 (#11087)future.v7_partialHydration
future 标志,该标志在服务器端渲染时启用数据路由器的部分水合 (#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
。我们发现大量应用程序依赖于此版本中修复的有 bug 的行为 (#11045)。我们在6.20.1
中恢复了修复,并将在后续版本中在 future 标志后面重新引入它。有关更多详细信息,请参见 #11052。
PathParam
类型 (#10719)v7_fetcherPersist
时,不要重新验证未卸载的 fetcher (#11044)resolveTo
路径解析的 bug (#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 更新,用于处理 pending/optimistic UI。
function handleClick() {
submit(data, { flushSync: true });
// Everything is flushed to the DOM so you can focus/scroll to your pending/optimistic UI
setFocusAndOrScrollToNewlyAddedThing();
}
useNavigate
/useSubmit
/fetcher.load
/fetcher.submit
添加 unstable_flushSync
选项,以便选择退出 React.startTransition
并选择加入 ReactDOM.flushSync
进行状态更新 (#11005)useBlocker
hook 中删除 unstable_
前缀,因为它已经使用了足够长的时间,我们对 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)
修复了当 to
位置带有尾部斜杠时 NavLink
的 active
逻辑 (#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 实例,而无需 prop-drillinguseFetchers
返回的 fetcher 上公开,以便可以通过 key
查找它们Form
和 useSubmit
现在支持可选的 navigate
/fetcherKey
props/params,以允许在后台启动 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 需要卸载的场景中,pending/optimistic UI 更加容易。
useFetchers()
API 始终应该只反映 pending/optimistic UI 的 in-flight fetcher 信息 —— 它并非旨在反映 fetcher 数据或在 fetcher 返回到 idle
状态后保留 fetcheruseFetchers()
中 - 它们在那里没有用途,因为您可以通过 useFetcher().data
访问数据idle
状态后清理useFetchers
保持公开,因此您仍然可以在卸载后访问 pending/optimistic 数据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 的示例用法,请查看 我们的 fork 的精彩 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
调用中,向错误消息添加 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
resolve/reject,则触发错误,以便与 loaders 和 actions 的行为相匹配,后者必须返回值或 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/[email protected]
完整更新日志: 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 中的默认行为将发生更改
请注意,为了避免破坏性更改,默认行为仍会将简单的键/值 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
实际上是一个补丁版本,但由于我们添加了一个新的 future 标志,因此带有 SemVer 次要版本升级。
future.v7_startTransition
tl;dr; 是 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
中,从而更好地支持 suspending 组件。这意味着,例如,如果目标路由中的组件之一 suspending 并且您没有提供 Suspense
边界来显示 fallback,则 React 将延迟新 UI 的渲染,并显示旧 UI,直到该异步操作 resolve。这对于等待诸如等待图像或 CSS 文件加载之类的事情可能很有用(从技术上讲,是的,您可以使用它进行数据加载,但我们仍然建议使用 loaders 😀)。有关此用法的快速概述,请查看 Ryan 在 Twitter 上的演示。
React.startTransition
包裹内部路由器状态更新 (#10438)PUSH
导航时,重新抛出 DOMException
(DataCloneError
)。 (#10427)jest
和 jsdom
(#10453)@remix-run/[email protected]
(更新日志)完整更新日志: 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/[email protected]
(更新日志)RouterProvider
时,useNavigate
/useSubmit
/fetcher.submit
现在在位置更改之间是稳定的,因为我们可以通过 @remix-run/router
实例处理相对路由,并摆脱对 useLocation()
的依赖 (#10336)BrowserRouter
时,这些 hooks 在位置更改之间仍然不稳定,因为它们仍然依赖于 useLocation()
action
提交或 router.revalidate
调用时重新验证 (#10344)Component
而不是 element
时无意中重新渲染的问题 (#10287)<Link to="//">
和其他无效的 URL 值 (#10367)<RouterProvider>
中,将内部 @remix-run/router
路由器状态同步从 useSyncExternalStore
切换到 useState
。我们发现了一些 细微的错误,其中路由器状态更新在其他正常的 useState
更新之前传播,这可能导致 useEffect
调用中的 foot guns。 (#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
,使其除了 errorElement
之外,还在路由上检查 ErrorBoundary
(#10190)createRoutesFromElements
中的 Fragments 时路由 ID 生成的问题 (#10193)shouldRevalidate
提供 fetcher 提交 (#10208)lazy()
错误 (#10201)DeferredData
的 instanceof
检查,以在 SSR 打包场景中对 ESM/CJS 边界具有弹性 (#10247)@remix-run/[email protected]
(#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() { ... }
为了保持应用程序 bundle 的小巧并支持路由的代码拆分,我们引入了一个新的 lazy()
路由属性。这是一个异步函数,它解析路由定义的非路由匹配部分(loader
、action
、element
/Component
、errorElement
/ErrorBoundary
、shouldRevalidate
、handle
)。
惰性路由在初始加载以及导航或 fetcher 调用的 loading
或 submitting
阶段解析。您不能惰性地定义路由匹配属性(path
、index
、children
),因为我们仅在匹配已知路由后才执行您的惰性路由函数。
您的 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>
);
然后在您的惰性路由模块中,导出您要为路由定义的属性
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
在 SSR 期间返回 IDLE_BLOCKER
的问题 (#10046)createStaticHandler
的 query()
方法中的 defer
加载器响应维护状态代码和标头 (#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
。这具有更好的跨浏览器支持,尤其是在 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
钩子 (#9709, #9932)<Form>
添加 preventScrollReset
prop (#9886)useBeforeUnload
添加了直通事件侦听器选项参数 (#9709)generatePath
的问题 (#9764)<Await>
以接受 ReactNode
作为 children 函数返回结果 (#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
此小版本发布主要是为了稳定我们的数据路由器的 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
,则抛出错误,因为重新验证需要知道加载器以前是否已执行。undefined
还会导致 SSR 字符串化以进行 hydration 期间出现问题。您应始终确保您的 loader
/action
返回一个值,如果您不希望返回任何内容,则可以返回 null
。 (#9511)basename
(#9591)ErrorResponse
正文,以在内部 403/404/405 场景中包含更具描述性的文本NavLink
和后代 <Routes>
中编码字符的问题 (#9589, #9647)ErrorResponse
实例 (#9593)basename
(#9591)@remix-run/[email protected]
[email protected]
完整变更日志: 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
<Link>
添加了 reloadDocument
prop。这允许 <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 升级的说明。