From 6751acf4deeae299d365c51e5ddd701520ba79a1 Mon Sep 17 00:00:00 2001 From: Sebastian Werner Date: Thu, 2 Feb 2023 14:35:59 +0100 Subject: [PATCH] feat: added support for React Router action() --- examples/react-router/src/routes/Index.tsx | 35 +++++++++++++++++----- src/loader.tsx | 12 +++++--- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/examples/react-router/src/routes/Index.tsx b/examples/react-router/src/routes/Index.tsx index 37c73ff..5cd0c4a 100644 --- a/examples/react-router/src/routes/Index.tsx +++ b/examples/react-router/src/routes/Index.tsx @@ -1,22 +1,33 @@ -import { Link, Outlet, useLoaderData } from "react-router-dom"; +import { ActionFunctionArgs, Form, Link, LoaderFunctionArgs, Outlet, useLoaderData } from "react-router-dom"; async function sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)) } -export interface LoaderResult { - firstName: string - name: string +export type LoaderResult = Record + +const fakeData: Record = { + firstName: "Gregory", + name: "Schmidt" } -export async function Loader(): Promise { +export async function Loader({ params }: LoaderFunctionArgs): Promise { + console.log("Loader Params:", params) + // This could be any `fetch()` which loads data from a remote await sleep(500) + return fakeData +} - return { - firstName: "Gregory", - name: "Schmidt" +export async function Action({ request }: ActionFunctionArgs) { + const formData = await request.formData(); + for (const [name, value] of formData) { + fakeData[name] = value } + + // This could be any `fetch()` which loads data from a remote + await sleep(1000) + return null } export default function Home() { @@ -27,6 +38,14 @@ export default function Home() { <>

Home Page (with Outlet to render children)

Howdy {x.firstName} {x.name}

+
+ + + + + +
+

  • Home
  • About
  • diff --git a/src/loader.tsx b/src/loader.tsx index 204d400..c4dbd48 100644 --- a/src/loader.tsx +++ b/src/loader.tsx @@ -1,5 +1,5 @@ import { lazy, Suspense } from "react"; -import type { ActionFunction, LoaderFunction, LoaderFunctionArgs } from 'react-router-dom' +import type { ActionFunction, LoaderFunction, LoaderFunctionArgs, ActionFunctionArgs } from 'react-router-dom' export type ElementFactory = () => JSX.Element @@ -13,10 +13,14 @@ export function modulesToLazyRouteObjects(imports: ReactRouterImportMap, root: s routeConfig[fileName.replace(root, "")] = { element: } />, - loader: async (params: LoaderFunctionArgs) => { + loader: async (args: LoaderFunctionArgs) => { const callback = await imports[fileName]().then((module) => module.Loader) - return callback ? callback(params) : null - } + return callback ? callback(args) : null + }, + action: async (args: ActionFunctionArgs) => { + const callback = await imports[fileName]().then((module) => module.Action) + return callback ? callback(args) : null + }, } }