react-router-dom
Advanced tools
Changelog
v6.9.0
Date: 2023-03-10
Component
/ErrorBoundary
route propertiesReact Router now supports an alternative way to define your route element
and errorElement
fields as React Components instead of React Elements. You can instead pass a React Component to the new Component
and ErrorBoundary
fields if you choose. There is no functional difference between the two, so use whichever approach you prefer š. You shouldn't be defining both, but if you do Component
/ErrorBoundary
will "win"
Example JSON Syntax
// Both of these work the same:
const elementRoutes = [{
path: '/',
element: <Home />,
errorElement: <HomeError />,
}]
const componentRoutes = [{
path: '/',
Component: Home,
ErrorBoundary: HomeError,
}]
function Home() { ... }
function HomeError() { ... }
Example JSX Syntax
// 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() { ... }
In order to keep your application bundles small and support code-splitting of your routes, we've introduced a new lazy()
route property. This is an async function that resolves the non-route-matching portions of your route definition (loader
, action
, element
/Component
, errorElement
/ErrorBoundary
, shouldRevalidate
, handle
).
Lazy routes are resolved on initial load and during the loading
or submitting
phase of a navigation or fetcher call. You cannot lazily define route-matching properties (path
, index
, children
) since we only execute your lazy route functions after we've matched known routes.
Your lazy
functions will typically return the result of a dynamic import.
// In this example, we assume most folks land on the homepage so we include that
// in our critical-path bundle, but then we lazily load modules for /a and /b so
// they don't load until the user navigates to those routes
let routes = createRoutesFromElements(
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="a" lazy={() => import("./a")} />
<Route path="b" lazy={() => import("./b")} />
</Route>
);
Then in your lazy route modules, export the properties you want defined for the 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>
);
}
An example of this in action can be found in the examples/lazy-loading-router-provider
directory of the repository. For more info, check out the lazy
docs.
š Huge thanks to @rossipedia for the Initial Proposal and POC Implementation.
route.Component
/route.ErrorBoundary
properties (#10045)route.lazy
(#10045)generatePath
incorrectly applying parameters in some cases (#10078)[react-router-dom-v5-compat]
Add missed data router API re-exports (#10171)Full Changelog: v6.8.2...v6.9.0
Changelog
v6.8.2
Date: 2023-02-27
<Link to>
as external if they are outside of the router basename
(#10135)basename
(#10076)<Link to>
urls (#10112)StaticRouterProvider
serialized hydration data (#10068)useBlocker
to return IDLE_BLOCKER
during SSR (#10046)defer
loader responses in createStaticHandler
's query()
method (#10077)invariant
to an UNSAFE_invariant
export since it's only intended for internal use (#10066)Full Changelog: v6.8.1...v6.8.2