SSR + Next.js is a bit confusing
I had a lot of trouble figuring out how to 'fill in' the needed code that was not shown in the example (I guess that is because it is WIP 🙂 )
Few comments from what I managed to figure out...
9 Replies
correct-apricotOP•14mo ago
I need to return an error from
onServerValidate
which then gets returned as action state, then it gets merged into my form state via useTransform
?
I am also guessing there is no way to specify errors by field but all are global errors? (that would be the formErrors
line)
In that line:
I am having a couple of issues:
1. state
coming from useActionState
is actually not guaranteed to not be null
, at least in an ordinary sever action, there is no requirement to return anything. I think the !
is making the code brittle. (as it is possible for state to be undefined
and throw an exception)correct-apricotOP•14mo ago
2.
transform
has type issues, not always but most of the time. It might be an error of mine but the result is a very long type error that is hard to figure out
correct-apricotOP•14mo ago
Maybe the server action needs to adhere to a much stricter type in order for all this to work?
For example in my code, some actions do not return result, some do a redirect, and some return a different type from the one the get as
previousState
from useActionState
These seemed to be perfectly valid server actions but they aren't valid for the typing and possibly the behavior of TTS Form's SSR.
Hm, after reading some more TypeScript definitions, it seems the correct way to handle the return type of useActionState
is to match the type of previousState
.
On a validation error this is easy as createServerValidate
gives us this with the exception return e.formState
On success though, there is no guidance.
I am guessing the expected behavior is to return:
Creating the values
object may not be trivial though (as it is done via decode
in the source code)>
I think some helper function would be the way to go.absent-sapphire•14mo ago
Thanks for all the feedback! Let's make the nextjs part more developer friendly 🙂
To begin with, this PR will probably help on the transform/useTransform typing issue.
Speaking of the return value of the actions... let's think about what we can do.
Can I ask which version of react/nextjs are you using? I'm seeing some errors with nextjs 14 while nextjs15 seems to be running fine
correct-apricotOP•14mo ago
I am using Next 15 canary + React 19 plus Zod.
I feel like applying the Zod validator changed some of the inferred types.
I am not sure if the code that
createServerValidate
saves is not replaced by equal amount of lines of code.
Since using server actions is actually super simple, and it is also async by default, I am not sure further enhancing of createServerValidate
is even needed. I can do all my validations and then just use a helper function to either return ok or error result.
I did add a PR to export the ServerFormState
type:
https://github.com/TanStack/form/pull/895
Still not there with the transform
typing. Will look into adding type tests.
Oh, I didn't realize #889 is not yet merged.absent-sapphire•14mo ago
Merged both now, thanks!
correct-apricotOP•14mo ago
Last release works great for
transform
typing.absent-sapphire•14mo ago
Still thinking about how to reduce boilerplate... if all you need is just merging into the form your errors/state coming from the server action, we could just hide this piece of code (notice the optional server state, do nothing if the action returns undefined)
Proposal:
So that the user only has to write:
correct-apricotOP•14mo ago
Recently I learned that server actions with
useActionState
are supposed to work exactly like a reducer, not sure why it took so long to figure out, maybe videos and documentation wasn't clear.
So, you pass any action and a state and return a new state in the same shape.
I think this is part of the 'boilerplate-ishness':
Sounds like a good idea to support undefined
or null
instead of this null object.
Basically, either return an error object for errors, or nothing for validation passed.
An alternative would be initialFormState
to be renamed to something like noErrorFormState
or okFormState
and make it so you do a return okFormState
to signify no errors.