in NextJs I want to create a component that displays a form, and fill this form by values from database.
the problem is that client component doesn’t support aync/await and server components doesn’t support neither useFormState() nor event handlers
async function MyForm({id}){
// supported in Client components only
let [state, submitAtion] = useActionState(...);
// await is supported in server components only
let value = await fetch(`https://example.com/value/${id}`);
// event handler is supported in Client components only
clickHandler(ev){
// handle the form
}
return (
<>
<form action={submitAtion}>
<input value={content} onChange={...} />
<button type="submit" />Submit</button>
<button onClick={clickHandler}>Submit</button>
</form>
</>
)
}
trials:
1- using server actions, but useActionState()
and useFormState()
are supported in client components only
2- convert MyForm
into a client component, but async/await is not supported in client components
3- move the button to a separate client component and keep the form in a server component, but the button cannot access the form data, and we cannot pass a function from MyForm into MyButton as it is not a serializable value
2
Answers
It doesn’t need to. You can use state to update the value being fetched from the server, and fetch that value in a
useEffect
. For example:When the component initially renders,
value
will beundefined
(or will be whatever initial value you provide touseState()
if you like). After thefetch
operation completes, the state value will be updated and the component will re-render.You do not need form states to submit a form to a server action.
Simply write your form in a server component and create a function for handling the data in your page file. Make sure to include
"use server";
in the top like this:And then in your Form Component you add the
name
attribute to your input fields which will later be their identifier in theformData
object.Like this:
You do not need to pass a value or onChange property to the input fields. Just the defaultValue, which you fetched on the server-side.
Make sure that your button is of type submit, so that it triggers the form action.