-
Notifications
You must be signed in to change notification settings - Fork 3
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
[Issue #236]: Server action example #341
base: main
Are you sure you want to change the base?
Conversation
Coverage report for
|
St.❔ |
Category | Percentage | Covered / Total |
---|---|---|---|
🟢 | Statements | 93.1% | 81/87 |
🟢 | Branches | 82.35% | 14/17 |
🟢 | Functions | 93.33% | 14/15 |
🟢 | Lines | 93.59% | 73/78 |
Test suite run success
16 tests passing in 5 suites.
Report generated by 🧪jest coverage report action from 7eeaf44
@@ -0,0 +1,84 @@ | |||
"use client"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there alternative approaches where the entire page doesn't need opted out of being a server component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No expert at this, but I believe you can have server only forms - but then you can't demo the client hooks like useFormStatus
and useFormState
(not that these hooks have to be used with a server action). For a server-based form, instead of useFormState
you would just call the server action function directly in the form's action attribute - but you can't do any user input in textboxes and such.
I'm not sure if another server (second) example makes sense for comparison? IE - Just call a server action from a server component page - and pass the resulting data down into a client component that displays it.
Just wanted to get things started on this cause I think it would have helped on our project if we had these examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think one alternative is to have a separate component for the part that depends on the client-only hook. I think for most forms it's likely just the submit button, so it might be something like:
// components/SubmitButton.tsx
"use client";
function SubmitButton(props) {
const { pending } = useFormStatus();
return <button disabled={pending} type="submit">{props.label}</button>;
}
I think that would then allow the page to be a server component with a small client-side island.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sawyerh this makes sense and we can try this - but we won't be able to demo useFormState
without making the form (and text inputs) client components. I updated it to use a page but with a client form component with useFormState
.
It can work with the form in a server component (with some eslint rules turned off (no-misused-promise
). Lmk if we want multiple examples or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be helpful for the example to also demonstrate how to test the page, as well as render it in Storybook.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can give tests and storybook a shot when we decide on how we want to construct these example(s)
Co-authored-by: Sawyer Hollenshead <[email protected]>
Also should this be in the nav? Not sure if in general we want the nav to just dynamically include all routes |
Ticket
Resolves #236
Changes
Context for reviewers
Chose the
useFormState
method (instead of just assigning the server action function to theaction
attribute of the form) . I believe this is a little more clear to handle returned data and possibly validation errorsI did not tie into an actual API call - though we could add as a follow on maybe (as described here Add example API request approach #116)
Believe we could use
useOptimistic
in the example to show, for example, showoptimisticName
immediately, then aserverActionReturnedName
when the server action completesthe example uses native
form
instead ofUSWDS
<Form>
. The USWDS<Form>
requires anonSubmit
handlerFor loading you might be able to tie in
useFormStatus
/pending
stateScreen.Recording.2024-05-29.at.4.56.46.PM.mov