From 7aa33268e5799b8683e6e7b6d1cf0c4b673b2872 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sun, 24 Mar 2024 13:43:08 +0900 Subject: [PATCH 1/2] test(react-server): test `ReactDom.useFormStatus` --- .../basic/src/routes/test/action/_action.tsx | 6 +- .../basic/src/routes/test/action/_client.tsx | 77 ++++++++++++++++++- .../basic/src/routes/test/action/page.tsx | 5 +- .../react-server/examples/basic/tsconfig.json | 2 +- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/packages/react-server/examples/basic/src/routes/test/action/_action.tsx b/packages/react-server/examples/basic/src/routes/test/action/_action.tsx index f05183df6..98019155d 100644 --- a/packages/react-server/examples/basic/src/routes/test/action/_action.tsx +++ b/packages/react-server/examples/basic/src/routes/test/action/_action.tsx @@ -1,6 +1,6 @@ "use server"; -import { tinyassert } from "@hiogawa/utils"; +import { sleep, tinyassert } from "@hiogawa/utils"; let counter = 0; @@ -25,3 +25,7 @@ export function addMessage(formData: FormData) { messages.push([messageId++, message]); messages = messages.slice(-5); } + +export async function slowAction(formData: FormData) { + await sleep(Number(formData.get("sleep"))); +} diff --git a/packages/react-server/examples/basic/src/routes/test/action/_client.tsx b/packages/react-server/examples/basic/src/routes/test/action/_client.tsx index f22aa4aab..2c76b83d0 100644 --- a/packages/react-server/examples/basic/src/routes/test/action/_client.tsx +++ b/packages/react-server/examples/basic/src/routes/test/action/_client.tsx @@ -1,7 +1,13 @@ "use client"; import React from "react"; -import { addMessage, changeCounter, type getMessages } from "./_action"; +import ReactDom from "react-dom"; +import { + addMessage, + changeCounter, + type getMessages, + slowAction, +} from "./_action"; export function Counter(props: { value: number }) { return ( @@ -90,3 +96,72 @@ export function Chat(props: { messages: ReturnType }) { ); } + +// https://react.dev/reference/react-dom/hooks/useFormStatus +export function FormStateTest() { + return ( +
+ + + ); +} + +function FormStateTestInner() { + // useFormStatus works only inside
+ const formStatus = ReactDom.useFormStatus(); + + return ( + <> +

Form Status

+
+ + + +
+
+        
pending: {String(formStatus.pending)}
+
method: {String(formStatus.method)}
+
+ data:{" "} + {formStatus.data + ? JSON.stringify(formDataToJson(formStatus.data)) + : String(formStatus.data)} +
+
action: {String(formStatus.action)}
+
+ + ); +} + +function formDataToJson(data: FormData) { + const result: any = {}; + data.forEach((v, k) => { + result[k] = v; + }); + return result; +} diff --git a/packages/react-server/examples/basic/src/routes/test/action/page.tsx b/packages/react-server/examples/basic/src/routes/test/action/page.tsx index eac1d8808..6ca1ccab8 100644 --- a/packages/react-server/examples/basic/src/routes/test/action/page.tsx +++ b/packages/react-server/examples/basic/src/routes/test/action/page.tsx @@ -1,15 +1,16 @@ import { changeCounter, getCounter, getMessages } from "./_action"; -import { Chat, Counter, Counter2 } from "./_client"; +import { Chat, Counter, Counter2, FormStateTest } from "./_client"; export default async function Page() { return ( -
+
+
); } diff --git a/packages/react-server/examples/basic/tsconfig.json b/packages/react-server/examples/basic/tsconfig.json index de09c2131..7d581715e 100644 --- a/packages/react-server/examples/basic/tsconfig.json +++ b/packages/react-server/examples/basic/tsconfig.json @@ -17,7 +17,7 @@ "module": "ESNext", "target": "ESNext", "lib": ["ESNext", "DOM"], - "types": ["vite/client", "react/experimental"], + "types": ["vite/client", "react/experimental", "react-dom/experimental"], "jsx": "react-jsx" } } From 88d78c3b821f748c1ed833dad5869bd7a1c9adda Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sun, 24 Mar 2024 13:48:15 +0900 Subject: [PATCH 2/2] test: e2e --- packages/react-server/examples/basic/e2e/basic.test.ts | 8 ++++++++ .../examples/basic/src/routes/test/action/_client.tsx | 6 +----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/react-server/examples/basic/e2e/basic.test.ts b/packages/react-server/examples/basic/e2e/basic.test.ts index 4b257d766..6c0c0d324 100644 --- a/packages/react-server/examples/basic/e2e/basic.test.ts +++ b/packages/react-server/examples/basic/e2e/basic.test.ts @@ -301,6 +301,14 @@ test("server action no js", async ({ browser }) => { await page.getByText("Count: 0").click(); }); +test("ReactDom.useFormStatus", async ({ page }) => { + await page.goto("/test/action"); + await page.getByText("hydrated: true").click(); + await page.getByRole("button", { name: "1.0 sec" }).click(); + await page.getByText("pending: true").click(); + await page.getByText("pending: false").click(); +}); + test("use client > virtual module", async ({ page }) => { await page.goto("/test/deps"); await page.getByText("TestVirtualUseClient").click(); diff --git a/packages/react-server/examples/basic/src/routes/test/action/_client.tsx b/packages/react-server/examples/basic/src/routes/test/action/_client.tsx index 2c76b83d0..866972700 100644 --- a/packages/react-server/examples/basic/src/routes/test/action/_client.tsx +++ b/packages/react-server/examples/basic/src/routes/test/action/_client.tsx @@ -100,11 +100,7 @@ export function Chat(props: { messages: ReturnType }) { // https://react.dev/reference/react-dom/hooks/useFormStatus export function FormStateTest() { return ( - + );