I want to get message back from server action, based on if validation and authentication was successful or not.
Login method is being called properly, I tried it out. The problem is that message is never shown in component file where the form is, it is never sent to LoginForm or saved in state.
actions.js:
"use server";
export async function login(previousState, formData) {
return {
message: "Please enter a valid email",
};
}
It uses useFormState. I saw that there is new useActionState, but it is not yet there, or not in my project version. The official Next.js docs use useFormState, but the URL leads to React's useActionState.
"use client";
import { useFormStatus, useFormState } from "react-dom";
const LoginForm = () => {
const initialState = {
message: "",
};
const [state, formAction] = useFormState(login, initialState); // error message never saves in state or shows on screen
useEffect(() => {
console.log("change:" + state);
}, [state]); // never changes so it is never triggered, except on load
return (
<form
action={formAction}
>
<div>
<label htmlFor="email">Email:</label>
<input
id="email"
name="email"
type="email"
required
/>
</div>
<div>
<SubmitButton />
<span>
{JSON.stringify(state)} // always {"message":""}
{state.message} // empty/""
</span>
<p aria-live="polite" className="sr-only">
{state?.message} // empty/""
</p>
</div>
</form>
);
};
const SubmitButton = () => {
const { pending } = useFormStatus(); // works well
return (
<button formAction={login} disabled={pending}>
{pending ? "Checking..." : " Log in"}
</button>
);
};
On the other hand, useFormStatus with pending status works well.
The problem was solved when I changed
<form action={formAction}>
with
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
formAction(formData);
};
...
<form onSubmit={handleSubmit}>