Skip to content

Commit 11c233a

Browse files
authored
Docs updates for lazy/Component/ErrorBoundary (#10178)
1 parent 12db33a commit 11c233a

File tree

2 files changed

+94
-4
lines changed

2 files changed

+94
-4
lines changed

docs/route/lazy.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,70 @@ export function ErrorBoundary() {
5959
ErrorBoundary.displayName = "SampleErrorBoundary";
6060
```
6161

62+
## Statically Defined Properties
63+
64+
Any properties defined statically on the route cannot be overwritten by the `lazy` function, and you'll receive a console warning if you attempt to overwrite them.
65+
66+
Additionally, as an optimization, if you statically define a `loader`/`action` then it will be called in parallel with the `lazy` function. This is useful if you have slim loaders that you don't mind on the critical bundle, and would like to kick off their data fetches in parallel with the component download. This is close to how Remix handles fetching because each route is it's own API route.
67+
68+
```js
69+
let route = {
70+
path: "projects",
71+
loader: ({ request }) => fetchDataForUrl(request.url),
72+
lazy: () => import("./projects"),
73+
};
74+
```
75+
76+
This also allows you to do more granular code splitting. For example, you could split your `loader` and `Component` into different files for parallel downloading:
77+
78+
```js
79+
let route = {
80+
path: "projects",
81+
async loader({ request, params }) {
82+
let { loader } = await import("./projects-loader");
83+
return loader({ request, params });
84+
},
85+
lazy: () => import("./projects-component"),
86+
};
87+
```
88+
89+
## Multiple Routes in a single file
90+
91+
While `lazy` may generally be used 1:1 with an async `import()` per route, you are free to implement a more advanced `lazy` function and just need to return the properties you want added to that route. This opens up some interesting possibilities.
92+
93+
For example, if you want to avoid loading multiple chunks for nested routes, you could store them all in the same file and return them to the individual routes. Modern bundlers will latch onto the same Promise for the different `import()` invocations.
94+
95+
```js
96+
// Assume pages/Dashboard.jsx has all of our loaders/components for multiple
97+
// dashboard routes
98+
let dashboardRoute = {
99+
path: "dashboard",
100+
async lazy() {
101+
let { Layout } = await import("./pages/Dashboard");
102+
return { Component: Layout };
103+
},
104+
children: [
105+
{
106+
index: true,
107+
async lazy() {
108+
let { Index } = await import("./pages/Dashboard");
109+
return { Component: Index };
110+
},
111+
},
112+
{
113+
path: "messages",
114+
async lazy() {
115+
let { messagesLoader, Messages } = await import(
116+
"./pages/Dashboard"
117+
);
118+
return {
119+
loader: messagesLoader,
120+
Component: Messages,
121+
};
122+
},
123+
},
124+
],
125+
};
126+
```
127+
62128
[pickingarouter]: ../routers/picking-a-router

docs/route/route.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,17 +296,27 @@ The route action is called when a submission is sent to the route from a [Form][
296296

297297
Please see the [action][action] documentation for more details.
298298

299-
## `element`
299+
## `element`/`Component`
300300

301-
The element to render when the route matches the URL.
301+
The React Element/Component to render when the route matches the URL.
302+
303+
If you want to create the React Element, use `element`:
302304

303305
```tsx
304306
<Route path="/for-sale" element={<Properties />} />
305307
```
306308

307-
## `errorElement`
309+
Otherwise use `Component` and React Router will create the React Element for you:
310+
311+
```tsx
312+
<Route path="/for-sale" Component={Properties} />
313+
```
314+
315+
## `errorElement`/`ErrorBoundary`
308316

309-
When a route throws an exception while rendering, in a `loader` or in an `action`, this element will render instead of the normal `element`.
317+
When a route throws an exception while rendering, in a `loader` or in an `action`, this React Element/Component will render instead of the normal `element`/`Component`.
318+
319+
If you want to create the React Element on your own, use `errorElement`:
310320

311321
```tsx
312322
<Route
@@ -324,6 +334,20 @@ When a route throws an exception while rendering, in a `loader` or in an `action
324334
/>
325335
```
326336

337+
Otherwise use `ErrorBoundary` and React Router will create the React Element for you:
338+
339+
```tsx
340+
<Route
341+
path="/for-sale"
342+
Component={Properties}
343+
loader={() => loadProperties()}
344+
action={async ({ request }) =>
345+
createProperty(await request.formData())
346+
}
347+
ErrorBoundary={ErrorBoundary}
348+
/>
349+
```
350+
327351
<docs-warning>If you are not using a data router like [`createBrowserRouter`][createbrowserrouter], this will do nothing</docs-warning>
328352

329353
Please see the [errorElement][errorelement] documentation for more details.

0 commit comments

Comments
 (0)