Skip to content

Commit

Permalink
Add actions and semi-splittable routes to playgrounds
Browse files Browse the repository at this point in the history
  • Loading branch information
markdalgleish committed Jan 16, 2025
1 parent 4da0737 commit 2fb37e0
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 12 deletions.
1 change: 1 addition & 0 deletions playground/split-route-modules-spa/app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export default [
index("routes/_index.tsx"),
route("splittable", "routes/splittable.tsx"),
route("unsplittable", "routes/unsplittable.tsx"),
route("semi-splittable", "routes/semi-splittable.tsx"),
] satisfies RouteConfig;
3 changes: 3 additions & 0 deletions playground/split-route-modules-spa/app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export default function Index() {
<li>
<Link to="/unsplittable">Unsplittable route</Link>
</li>
<li>
<Link to="/semi-splittable">Semi-splittable route</Link>
</li>
</ul>
</div>
);
Expand Down
30 changes: 30 additions & 0 deletions playground/split-route-modules-spa/app/routes/semi-splittable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Form, useLoaderData, useActionData } from "react-router";

// Dummy variable to prevent route exports from being split
let shared: null = null;

export const clientLoader = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return shared ?? "Hello from unsplittable client loader";
};

export const clientAction = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return "Hello from splittable client action";
};

export default function Hello() {
const message = useLoaderData() as Awaited<ReturnType<typeof clientLoader>>;
const actionData = useActionData() as Awaited<
ReturnType<typeof clientAction>
>;
return (
<>
<p>{message}</p>
<p>{actionData}</p>
<Form method="post">
<button>Submit</button>
</Form>
</>
);
}
22 changes: 17 additions & 5 deletions playground/split-route-modules-spa/app/routes/splittable.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import { useLoaderData } from "react-router";
import { Form, useLoaderData, useActionData } from "react-router";

export const clientLoader = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return "Hello from splittable client loader";
};

// Uncomment the following line to see an error message since HydrateFallback is
// not a valid export outside of the root route in SPA mode:
// export function HydrateFallback() {}
export const clientAction = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return "Hello from splittable client action";
};

export default function Hello() {
const message = useLoaderData() as Awaited<ReturnType<typeof clientLoader>>;
return <div>{message}</div>;
const actionData = useActionData() as Awaited<
ReturnType<typeof clientAction>
>;
return (
<>
<p>{message}</p>
<p>{actionData}</p>
<Form method="post">
<button>Submit</button>
</Form>
</>
);
}
22 changes: 19 additions & 3 deletions playground/split-route-modules-spa/app/routes/unsplittable.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import { useLoaderData } from "react-router";
import { Form, useLoaderData, useActionData } from "react-router";

// Dummy variable to prevent route exports from being split
let shared: null = null;

export const clientLoader = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return shared ?? "Hello from splittable client loader";
return shared ?? "Hello from unsplittable client loader";
};

export const clientAction = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return shared ?? "Hello from unsplittable client action";
};

export default function Hello() {
const message = useLoaderData() as Awaited<ReturnType<typeof clientLoader>>;
return shared ?? <div>{message}</div>;
const actionData = useActionData() as Awaited<
ReturnType<typeof clientAction>
>;
return (
<>
<p>{message}</p>
<p>{actionData}</p>
<Form method="post">
<button>Submit</button>
</Form>
</>
);
}
1 change: 1 addition & 0 deletions playground/split-route-modules/app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export default [
index("routes/_index.tsx"),
route("splittable", "routes/splittable.tsx"),
route("unsplittable", "routes/unsplittable.tsx"),
route("semi-splittable", "routes/semi-splittable.tsx"),
] satisfies RouteConfig;
3 changes: 3 additions & 0 deletions playground/split-route-modules/app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export default function Index() {
<li>
<Link to="/unsplittable">Unsplittable route</Link>
</li>
<li>
<Link to="/semi-splittable">Semi-splittable route</Link>
</li>
</ul>
</div>
);
Expand Down
34 changes: 34 additions & 0 deletions playground/split-route-modules/app/routes/semi-splittable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Form, useLoaderData, useActionData } from "react-router";

// Dummy variable to prevent route exports from being split
let shared: null = null;

export const clientLoader = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return shared ?? "Hello from unsplittable client loader";
};

export const clientAction = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return "Hello from splittable client action";
};

export function HydrateFallback() {
return shared ?? <div>Loading...</div>;
}

export default function Hello() {
const message = useLoaderData() as Awaited<ReturnType<typeof clientLoader>>;
const actionData = useActionData() as Awaited<
ReturnType<typeof clientAction>
>;
return (
<>
<p>{message}</p>
<p>{actionData}</p>
<Form method="post">
<button>Submit</button>
</Form>
</>
);
}
20 changes: 18 additions & 2 deletions playground/split-route-modules/app/routes/splittable.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
import { useLoaderData } from "react-router";
import { Form, useLoaderData, useActionData } from "react-router";

export const clientLoader = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return "Hello from splittable client loader";
};

export const clientAction = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return "Hello from splittable client action";
};

export function HydrateFallback() {
return <div>Loading...</div>;
}

export default function Hello() {
const message = useLoaderData() as Awaited<ReturnType<typeof clientLoader>>;
return <div>{message}</div>;
const actionData = useActionData() as Awaited<
ReturnType<typeof clientAction>
>;
return (
<>
<p>{message}</p>
<p>{actionData}</p>
<Form method="post">
<button>Submit</button>
</Form>
</>
);
}
20 changes: 18 additions & 2 deletions playground/split-route-modules/app/routes/unsplittable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useLoaderData } from "react-router";
import { Form, useLoaderData, useActionData } from "react-router";

// Dummy variable to prevent route exports from being split
let shared: null = null;
Expand All @@ -8,11 +8,27 @@ export const clientLoader = async () => {
return shared ?? "Hello from unsplittable client loader";
};

export const clientAction = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return shared ?? "Hello from unsplittable client action";
};

export function HydrateFallback() {
return shared ?? <div>Loading...</div>;
}

export default function Hello() {
const message = useLoaderData() as Awaited<ReturnType<typeof clientLoader>>;
return shared ?? <div>{message}</div>;
const actionData = useActionData() as Awaited<
ReturnType<typeof clientAction>
>;
return (
<>
<p>{message}</p>
<p>{actionData}</p>
<Form method="post">
<button>Submit</button>
</Form>
</>
);
}

0 comments on commit 2fb37e0

Please sign in to comment.