Skip to content

Commit ebd70a6

Browse files
authored
Merge pull request #11961 from remix-run/pedro/vmod-for-with-props-hocs
refactor: withprops hocs from virtual module
2 parents c3d95f0 + 4a06638 commit ebd70a6

File tree

7 files changed

+83
-56
lines changed

7 files changed

+83
-56
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"@react-router/dev": minor
3+
"react-router": minor
4+
---
5+
6+
Params, loader data, and action data as props for route component exports
7+
8+
```tsx
9+
export default function Component({ params, loaderData, actionData }) {}
10+
11+
export function HydrateFallback({ params }) {}
12+
export function ErrorBoundary({ params, loaderData, actionData }) {}
13+
```

packages/react-router-dev/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"arg": "^5.0.1",
5454
"babel-dead-code-elimination": "^1.0.6",
5555
"chalk": "^4.1.2",
56+
"dedent": "^1.5.3",
5657
"es-module-lexer": "^1.3.1",
5758
"exit-hook": "2.2.1",
5859
"fs-extra": "^10.0.0",

packages/react-router-dev/vite/plugin.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import {
4545
resolveEntryFiles,
4646
resolvePublicPath,
4747
} from "./config";
48-
import { withProps } from "./with-props";
48+
import * as WithProps from "./with-props";
4949

5050
export async function resolveViteConfig({
5151
configFile,
@@ -1414,6 +1414,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => {
14141414
}
14151415
},
14161416
},
1417+
WithProps.plugin,
14171418
{
14181419
name: "react-router-route-exports",
14191420
async transform(code, id, options) {
@@ -1454,7 +1455,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => {
14541455

14551456
let ast = parse(code, { sourceType: "module" });
14561457
removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
1457-
withProps(ast);
1458+
WithProps.transform(ast);
14581459
return generate(ast, {
14591460
sourceMaps: true,
14601461
filename: id,

packages/react-router-dev/vite/with-props.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,61 @@
1+
import type { Plugin } from "vite";
2+
import dedent from "dedent";
3+
14
import type { Babel, NodePath, ParseResult } from "./babel";
25
import { traverse, t } from "./babel";
6+
import * as VirtualModule from "./vmod";
7+
8+
const vmodId = VirtualModule.id("with-props");
39

410
const NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
511

6-
export const withProps = (ast: ParseResult<Babel.File>) => {
12+
export const plugin: Plugin = {
13+
name: "react-router-with-props",
14+
enforce: "pre",
15+
resolveId(id) {
16+
if (id === vmodId) return VirtualModule.resolve(vmodId);
17+
},
18+
async load(id) {
19+
if (id !== VirtualModule.resolve(vmodId)) return;
20+
return dedent`
21+
import { createElement as h } from "react";
22+
import { useActionData, useLoaderData, useParams } from "react-router";
23+
24+
export function withComponentProps(Component) {
25+
return function Wrapped() {
26+
const props = {
27+
params: useParams(),
28+
loaderData: useLoaderData(),
29+
actionData: useActionData(),
30+
};
31+
return h(Component, props);
32+
};
33+
}
34+
35+
export function withHydrateFallbackProps(HydrateFallback) {
36+
return function Wrapped() {
37+
const props = {
38+
params: useParams(),
39+
};
40+
return h(HydrateFallback, props);
41+
};
42+
}
43+
44+
export function withErrorBoundaryProps(ErrorBoundary) {
45+
return function Wrapped() {
46+
const props = {
47+
params: useParams(),
48+
loaderData: useLoaderData(),
49+
actionData: useActionData(),
50+
};
51+
return h(ErrorBoundary, props);
52+
};
53+
}
54+
`;
55+
},
56+
};
57+
58+
export const transform = (ast: ParseResult<Babel.File>) => {
759
const hocs: Array<[string, Babel.Identifier]> = [];
860
function getHocUid(path: NodePath, hocName: string) {
961
const uid = path.scope.generateUidIdentifier(hocName);
@@ -72,7 +124,7 @@ export const withProps = (ast: ParseResult<Babel.File>) => {
72124
hocs.map(([name, identifier]) =>
73125
t.importSpecifier(identifier, t.identifier(name))
74126
),
75-
t.stringLiteral("react-router")
127+
t.stringLiteral(vmodId)
76128
)
77129
);
78130
}

packages/react-router/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,6 @@ export {
133133
useRouteLoaderData,
134134
useRoutes,
135135
} from "./lib/hooks";
136-
export {
137-
withComponentProps,
138-
withHydrateFallbackProps,
139-
withErrorBoundaryProps,
140-
} from "./lib/hocs";
141136

142137
// Expose old RR DOM API
143138
export type {

packages/react-router/lib/hocs.tsx

Lines changed: 0 additions & 47 deletions
This file was deleted.

pnpm-lock.yaml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)