Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support partial hydration for Remix clientLoader/clientAction #11033

Merged
merged 19 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 44 additions & 0 deletions .changeset/partial-hydration-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
"@remix-run/router": minor
---

Add a new `future.v7_partialHydration` future flag which enables partial hydration of a `RouterProvider`. This means that you can provide `hydrationData.loaderData` that has _some_ values in it - but not necessarily a value for every initially matched route that contains a loader. The router will call _only_ the loaders that do not have data on initalization, and it will render down to the deepest provided `Fallback` element (up to the first route without hydration data) while it executes the remaining loaders.

For example, the following router has a `root` and `index` route, but only provided `hydrationData.loaderData` for the `root` route. Because the `index` route has a `loader`, we need to run that during initialization. With `future.v7_partialHydration` specified, `<RouterProvider>` will render the `RootComponent` (because it has data) and then the `IndexFallback` (since it does not have data).

```jsx
let router = createBrowserRouter(
[
{
id: "root",
path: "/",
loader: rootLoader,
Component: RootComponent,
Fallback: RootFallback,
children: [
{
id: "index",
index: true,
loader: indexLoader,
Component: IndexComponent,
Fallback: IndexFallback,
},
],
},
],
{
future: {
v7_partialHydration: true,
},
hydrationData: {
loaderData: {
root: { message: "Hydrated from Root!" },
},
},
}
);
```

If the above example did not have an `IndexFallback`, then `RouterProvider` would instead render the `RootFallback` while it executed the `indexLoader`.

**Note:** When `future.v7_partialHydration` is provided, the `<RouterProvider fallbackElement>` prop is ignored since you can move it to a `Fallback` on your top-most route. The `fallbackElement` prop will be deprecated in React Router v7 when `v7_partialHydration` behavior becomes the standard behavior.
4 changes: 3 additions & 1 deletion docs/route/route.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ interface RouteObject {
loader?: LoaderFunction;
action?: ActionFunction;
element?: React.ReactNode | null;
Component?: React.ComponentType | null;
fallbackElement?: React.ReactNode | null;
errorElement?: React.ReactNode | null;
Component?: React.ComponentType | null;
Fallback?: React.ComponentType | null;
ErrorBoundary?: React.ComponentType | null;
handle?: RouteObject["handle"];
shouldRevalidate?: ShouldRevalidateFunction;
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@
},
"filesize": {
"packages/router/dist/router.umd.min.js": {
"none": "49.4 kB"
"none": "49.8 kB"
},
"packages/react-router/dist/react-router.production.min.js": {
"none": "13.9 kB"
"none": "14.3 kB"
},
"packages/react-router/dist/umd/react-router.production.min.js": {
"none": "16.3 kB"
"none": "16.7 kB"
},
"packages/react-router-dom/dist/react-router-dom.production.min.js": {
"none": "16.7 kB"
Expand Down