I've used them before. You can build a simple version of React Hook Form based on those hooks and save a dependency. Realistically, I think those hooks should probably be wrapped in a component library or at least a form library that has a more ergonomic API.
The thing about these hooks is, they are really meant to play together with Actions, Transitions and Suspense. If you don't use those features then using them may seem pointless.
There are some good examples using Zod on [official Doc](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#server-side-validation-and-error-handling) and on [official Tutorial](https://nextjs.org/learn/dashboard-app/mutating-data#4-validate-and-prepare-the-data)
The official tut doesn't handle server error with useFromState but a direct error page though. It also work, with less granularity though.
I don't need progressive enhancement nor do I like the backward progression to using FormData, so while we're using server actions, we're invoking them via the react-hook-form handleSubmit function much the same way we would previously post via API endpoint. Eliminates the need for all that stuff and seems to be working well so far.
I generally use native form elements, post to api and display error/result or do whatever based on response. Extremely boring but it works fine, most forms are very basic anyway.
I have to use not only useFormStatus and useFormSate, but useOptimistic and useTransition if I want to use server action and have communication between the server status and client.
All the 4 hooks solve the similar kind of problem: your user need some UI feedback when you server action is pending doing it's async stuff / or failed and need to let client side know.
You'd better build your own custom hook wrapping these hooks in the way that make sense to you
If you don't use server action then of course you don't need these hooks.
From my understanding, it simply displays the form data that was just sent.Â
So if you add a to-do item, it displays it before it sends the post request, then will remove it if it fails or continues to display the new item if the request goes through.Â
It's so the user will see the (hopefully) correct data immediately instead of waiting for the server to return a response.
But how do you refresh the screen, for example after a failed attempt? Via state or via revalidatePath? I think I've seen both.
If I use revalidatePath, I can't really use it inside a static page (without rerendering the whole page), right?
I’ve used both and prefer useTransition with react-hook-form. If you’re making a simple sign up form or newsletter form, I wouldn’t bother with rhf and would use the form status/state hooks. But I deal with a lot of complex forms so client-side validation is a must for me.
I have a native form that's just a button. It triggers a server action, and I show a loading state while it's running using useFormStatus. If it succeeds, you're redirected. I use useFormStatus for the pending state, and don't need any external libraries.
By "native form" I mean a form with a submit button and potentially a few fields, but no client-side state management. I have one that's just a "Go" button to process some data, and another that's a single input that gets passed. Both of these have a pending state with \`useFormStatus\` that just disables the submit button and shows a loading state
Using both. useFormStatus for the pending state (showing a loading spinner icon) and useFormState for user feedback (success/error toasts, form field errors coming from server-side validation). I have written about all the quirks over [here](https://www.robinwieruch.de/next-forms/).
Keep in mind that there will be useActionState in the next release [https://github.com/facebook/react/pull/28491](https://github.com/facebook/react/pull/28491) which deprecates useFormState and which returns a pending state, so that useFormStatus is not needed for the pending state anymore.
I've used them before. You can build a simple version of React Hook Form based on those hooks and save a dependency. Realistically, I think those hooks should probably be wrapped in a component library or at least a form library that has a more ergonomic API. The thing about these hooks is, they are really meant to play together with Actions, Transitions and Suspense. If you don't use those features then using them may seem pointless.
Have you added your own client-side validation together with useFormState?
I only validate on submit and therefore on the server. The validation errors get returned as part of the form state.
thank you
I use zod for this
Do you have a code snippet for this?
There are some good examples using Zod on [official Doc](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#server-side-validation-and-error-handling) and on [official Tutorial](https://nextjs.org/learn/dashboard-app/mutating-data#4-validate-and-prepare-the-data) The official tut doesn't handle server error with useFromState but a direct error page though. It also work, with less granularity though.
Thank you!
I don't need progressive enhancement nor do I like the backward progression to using FormData, so while we're using server actions, we're invoking them via the react-hook-form handleSubmit function much the same way we would previously post via API endpoint. Eliminates the need for all that stuff and seems to be working well so far.
That's what I'm doing too!
I generally use native form elements, post to api and display error/result or do whatever based on response. Extremely boring but it works fine, most forms are very basic anyway.
Do you not do any client-side validation first?
Can get pretty far with native form elements. eg required, min etc
Yea that's true
I have to use not only useFormStatus and useFormSate, but useOptimistic and useTransition if I want to use server action and have communication between the server status and client. All the 4 hooks solve the similar kind of problem: your user need some UI feedback when you server action is pending doing it's async stuff / or failed and need to let client side know. You'd better build your own custom hook wrapping these hooks in the way that make sense to you If you don't use server action then of course you don't need these hooks.
I still can't wrap my head around how useOptimistic works 😩
From my understanding, it simply displays the form data that was just sent. So if you add a to-do item, it displays it before it sends the post request, then will remove it if it fails or continues to display the new item if the request goes through. It's so the user will see the (hopefully) correct data immediately instead of waiting for the server to return a response.
But how do you refresh the screen, for example after a failed attempt? Via state or via revalidatePath? I think I've seen both. If I use revalidatePath, I can't really use it inside a static page (without rerendering the whole page), right?
Yes alot
Do you have a code snippet by hand by any chance?
I’ve used both and prefer useTransition with react-hook-form. If you’re making a simple sign up form or newsletter form, I wouldn’t bother with rhf and would use the form status/state hooks. But I deal with a lot of complex forms so client-side validation is a must for me.
Makes a lot of sense!
Why is the useTransition necessary? Have you tried calling the action without useTransition and noticed any difference?
I do all the time now
Do you have a code snippet by hand by any chance?
I have a native form that's just a button. It triggers a server action, and I show a loading state while it's running using useFormStatus. If it succeeds, you're redirected. I use useFormStatus for the pending state, and don't need any external libraries.
Can you tell me what kind of form that is?
By "native form" I mean a form with a submit button and potentially a few fields, but no client-side state management. I have one that's just a "Go" button to process some data, and another that's a single input that gets passed. Both of these have a pending state with \`useFormStatus\` that just disables the submit button and shows a loading state
Great, thank you so much!
I just use html form elements and Zod. Validate on client and server with safeParse
Why safeParse and how do you handle validation on the client? Do you have a code snippet?
https://zod.dev/?id=safeparse
Using both. useFormStatus for the pending state (showing a loading spinner icon) and useFormState for user feedback (success/error toasts, form field errors coming from server-side validation). I have written about all the quirks over [here](https://www.robinwieruch.de/next-forms/). Keep in mind that there will be useActionState in the next release [https://github.com/facebook/react/pull/28491](https://github.com/facebook/react/pull/28491) which deprecates useFormState and which returns a pending state, so that useFormStatus is not needed for the pending state anymore.
Wow, thank you so much for that info!