Now, one way of working around,
and not the only way as you will soon see,
would be to create a new component, a PostForm Component,
for example, in a separate post-form.js file.
Here, I'll create a separate PostForm Component Function.
And the idea behind this component,
is to have all that code that includes useFormState,
and the rendering of this form,
so that I grab all that code from the NewPostPage JS file
and move that into the PostForm Component like this.
And I need a closing bracket here.
So now the PostForm Component has the useFormState hook
and all the markup that renders the form.
Now, it won't work like this.
For example, the FormSubmit import is missing
and the useFormState hook import is missing.
And of course, we don't have access
to this createPost action here,
so we need to fix these things.
And I'll start with the imports in page.js,
I will actually grab the import of the useFormState hook
and remove it from there.
And then actually also remove
the Use Client Directive from there,
cut all that and add it here at the top
of the PostForm Component file.
And I'll also grab this FormSubmit Component import,
cut it from the NewPostPage file
and add that here in the PostForm JS file instead.
Now that form and that hook here is in a separate component.
Now that hook needs access
to the createPost Server action though.
And what we can do here,
and what works is that we simply accept that as a Prop,
because you can pass Server Actions through Props
and you can indeed pass them from a React Server Component
to a Client Component.
That works and is allowed.
You just can't define them in a Client Component file,
but you can pass them from a Server Component
to a Client Component.
And that's what I'll do here.
Now, I'll name my prop Action
and then use that prop here
as a value in the useFormState hook.
And with that done back here in the page.js file,
we can and should go down there
and now simply return that PostForm
and set this action prop
to the createPost Server action function like this.
And with that, we're now defining
that Server Action in a Server Component,
which is how it should be.
And we're then passing it to a Client Component,
which will work.
And now with that, if we do that, you see the error is gone
and this New Post Page reloads successfully.
You will also see however, that if I now click Create Post,
I'm getting some error.
I'm getting some error
that formData.get is not a function.
So that code in my formAction suddenly fails.
And previously, it of course, worked fine.
Why is that the case?
Well, the code in this formAction is now failing,
because now, we no longer get formData
as a first argument in that Server Action.
And we're no longer getting that,
because we're funneling this Server Action
through the useFormState hook.
We're passing it as a first argument to useFormState.
Now, I mentioned that we get back a new formAction,
which we can set on the form,
but React will actually not just listen to the submission
of the form and update that state,
but it will also change the way the formAction,
the server action we're passing to useFormState
will be called.
It will still give us access to the formData,
but it will no longer do so as a first argument.
Instead, the first argument will be the previous
form state now and the second argument
will be the submitted formData.
So if we had more complex logic in our Server Action,
where we might want to return a new form state
based on the previous form state,
we could do that with help of that prevState object,
which we get automatically,
because we're passing this Server Action
to the useFormState hook.
And in our case that, for example, would give us
that initial state object.
That's what we could retrieve from prevState.
Here, I don't need it,
but still this is how we now need
to write this Server Action,
because the formData will now actually be
the second argument.
So with that though, we will be able
to click Create Post without getting an error.
But of course, we now don't get any feedback here.
We don't see those error messages we're creating
in our server side code.
And the reason for that simply
is that we're not using this state yet.
And keep in mind that this state will be that object
that has this errors property,
which stores this errors array.
But we're not using that.
Hence of course, we're not showing it on the screen.
But we can now simply use it here in the PostForm Component
to output those error messages.
For example, by going to the bottom of this form,
and then here we can output those error messages dynamically
by checking if state.errors is defined.
So if we have an errors property in the state object,
and if that's the case,
I wanna output an unordered list here,
which I'll give a className of form-errors.
And then here inside of that unordered list,
I wanna map my errors.
So my error messages, which are strings, to list items.
Now every list item will receive a key,
which is simply the error message,
and then I'll output the error message
between those list item tags.
Well, and with that, if you saved it,
you should now see those error messages down there,
if you're not submitting any data.
Now as you see, I don't get any error regarding the image,
even though I haven't added any image here,
because indeed image will always be an object,
even if nothing was submitted.
And therefore, I actually wanna add an extra check here
and check if image.size is equal to zero,
which means it's an invalid image file.
With this extra check added,
now, I also get this image error message,
if no image file was chosen.
And with that, we now made sure
that we don't just give the users some feedback
regarding whether the form is being submitted or not,
but that we also provide some validation to the user,
some server side validation,
around which the user can't work.