Getting weird error in the form action by using Server Action #56234
Replies: 24 comments 40 replies
-
You must declare
|
Beta Was this translation helpful? Give feedback.
-
Latest update on nextjs demo commerce store using experimental feature of react: Throws same error when button is disabled. You can see it here if you inspect disabled button:
|
Beta Was this translation helpful? Give feedback.
-
I encountered this bug earlier. The cause is that I was passing a handler function just like I would on a onSubmit handler. I realized it was a mistake. You can only pass the action directly to the action attribute. Do not pass any handlers whatsoever. ❌ const onSubmitHandler = (formData: FormData) => {
// do something
actionHandler(formData)
}
<form action={onSubmitHandler}></form> ☑️
I hope this helps someone who face the same issue. |
Beta Was this translation helpful? Give feedback.
-
I got this error because I had both This is WRONG:
Correct:
|
Beta Was this translation helpful? Give feedback.
-
i got this when i tried to automate 100+ signup submissions using fetch api. i guess that's not possible with server actions. here's my code: rate-limit/utils.tsimport { parse } from 'node-html-parser'
export const LOCALHOST_URL = 'http://localhost:3000'
export async function getActionNo(): Promise<string> {
const res = await fetch(`${LOCALHOST_URL}/signup`)
const html = await res.text()
const $ = parse(html)
const str = $.querySelector('input[name="$ACTION_1:0"]')
?.getAttribute('value')
?.toString() as string
const data = JSON.parse(str)
return data.id
} rate-limit/signup.tsimport { LOCALHOST_URL, getActionNo } from 'rate-limit/utils'
async function main() {
const actionNumber = await getActionNo()
const formData = new FormData()
formData.append('email', 'a@a.com')
const res = await fetch(`${LOCALHOST_URL}/signup`, {
method: 'POST',
credentials: 'same-origin',
body: formData,
headers: {
'Next-Action': actionNumber,
},
})
const data = await res.text()
console.log({ res, data })
}
main() I'm still trying it here but I think I have to use Puppeteer/Playwright with it. Idk if there's an easier alternative. |
Beta Was this translation helpful? Give feedback.
-
I added In other places, I was using |
Beta Was this translation helpful? Give feedback.
-
Issue is still there. All you have to do is navigate from one route to the route that contains the |
Beta Was this translation helpful? Give feedback.
-
I had the same issue: some of my forms were throwing an error The answer was simple: I had this |
Beta Was this translation helpful? Give feedback.
-
I have this error in every |
Beta Was this translation helpful? Give feedback.
-
Thanx to @gumpen. For me solution was to add 'use client' in submit component. Double check all form elements in you for. If form is a Client component, all children must be Client component with |
Beta Was this translation helpful? Give feedback.
-
Any news with this? none of the solutions here seemed to help. I don't have any nested forms, I have 'use client' where it needs to be, anytime I use the router (or link) to route to a component with a form, I get this error, no matter what. |
Beta Was this translation helpful? Give feedback.
-
ProblemThis error may be caused by several different reasons. When I inspected my form, I saw this text in the browser's rendered DOM attached to my
When I clicked on the "Error" notification which was rendered by Next.js, I saw this error:
SolutionIn my case, the issue was /(auth)
/(auth)/layout.tsx <-- removing this fixes the error
/(auth)/signup/page.tsx <-- the error is no longer on this page The layout page has a full-screen style (e.g., |
Beta Was this translation helpful? Give feedback.
-
"use client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { zodResolver } from "@hookform/resolvers/zod";
import { Loader, User2 } from "lucide-react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";
import { useForm } from "react-hook-form";
import * as z from "zod";
import { Bounce, ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { doSocialLogin } from "@/actions/auth.actions";
const formSchema = z.object({
email: z.string().email({ message: "Enter a valid email address" }),
// password: z.string().min(6),
});
type UserFormValue = z.infer<typeof formSchema>;
export default function UserAuthForm() {
const [isLoading, setIsLoading] = useState(false);
const router = useRouter()
const { register, handleSubmit, reset, formState: { errors, isSubmitSuccessful } } = useForm()
const searchParams = useSearchParams();
const callbackUrl = searchParams.get("callbackUrl");
const [loading, setLoading] = useState(false);
const defaultValues = {
email: "demo@gmail.com",
};
const form = useForm<UserFormValue>({
resolver: zodResolver(formSchema),
defaultValues,
});
const onSigninSubmit = async (data: any /**UserFormValue */) => {
// signIn("credentials", {
// email: data.email,
// callbackUrl: callbackUrl ?? "/dashboard",
// });
console.log(data)
setIsLoading(true);
// Simulate a network request or actual form submission here
setTimeout(() => {
setIsLoading(false);
// Handle navigation or further steps after account creation
}, 2000);
setTimeout(() => {
toast.success('Sign in successfull!', {
position: "top-right",
autoClose: 3000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
// progress: undefined,
theme: "light",
transition: Bounce,
});
}, 2000);
setTimeout(() => { router.push('/dashboard') }, 3100)
};
return (
<div className="w-2/3 mx-auto bg-gray-100 rounded-md p-4">
<h2>TeleMed</h2>
<form onSubmit={handleSubmit(onSigninSubmit)} className="mt-4 flex flex-col items-center">
<ToastContainer
position="top-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light"
// transition:Bounce,
/>
<div className="w-full flex-1">
{/* */}
<GoogleButton />
{/* */}
<h2 className="my-2 text-xl text-center text-[#283779]">
Or Use Email/Password
</h2>
<div className="w-2/3 mx-auto">
<Input
{...register('email', { required: true })}
className="w-full px-2 py-6 rounded-lg font-light bg-gray-100 border border-gray-200
placeholder-gray-500 text-sm focus:outline-none focus:border-gray-400 focus:bg-white mt-5"
type="email" placeholder="Email" />
{errors?.email && <span className="text-sm font-light text-red-500">Please enter a valid email.</span>}
<Input
{...register('password', { required: true })}
className="w-full px-2 py-6 rounded-lg font-light bg-gray-100 border border-gray-200
placeholder-gray-500 text-sm focus:outline-none focus:border-gray-400 focus:bg-white mt-5"
type="password" placeholder="Password" />
{errors?.password && <span className="text-sm font-light text-red-500">This field is required.</span>}
<Button
type='submit'
className="mt-5 tracking-wide font-light text-white w-full py-6
rounded-lg transition-all duration-300 ease-in-out flex items-center
justify-center focus:shadow-outline focus:outline-none">
{
isLoading ? (<>
<span className="flex gap-1 text-green-200"><Loader className="animate-spin" />{' '} Signing in....</span>
</>) : (<>
<User2 />
<span className="mx-2">
Sign In
</span>
</>)
}
</Button>
<span className="block text-gray-800 my-3">
No account yet?
<Link href={'/auth/signup'} className="text-green-800">
{' '} Register instead
</Link>
</span>
<span className="block text-blue-500 my-3">
<Link href={'/auth/reset-password'} className="text-blue-600">
{' '} Reset Password
</Link>
</span>
</div>
</div>
</form>
</div>
);
}
function GoogleButton() {
return (
<form action={doSocialLogin}>
<div className="flex flex-col items-center">
<button
onClick={() => { }}
className="w-full max-w-xs font-bold shadow-sm bg-white rounded-lg py-3 text-gray-800 flex items-center justify-center transition-all duration-300 ease-in-out focus:outline-none hover:shadow focus:shadow-sm focus:shadow-outline">
<div className="bg-white p-2 rounded-full">
<svg className="w-4" viewBox="0 0 533.5 544.3">
<path
d="M533.5 278.4c0-18.5-1.5-37.1-4.7-55.3H272.1v104.8h147c-6.1 33.8-25.7 63.7-54.4 82.7v68h87.7c51.5-47.4 81.1-117.4 81.1-200.2z"
fill="#4285f4" />
<path
d="M272.1 544.3c73.4 0 135.3-24.1 180.4-65.7l-87.7-68c-24.4 16.6-55.9 26-92.6 26-71 0-131.2-47.9-152.8-112.3H28.9v70.1c46.2 91.9 140.3 149.9 243.2 149.9z"
fill="#34a853" />
<path
d="M119.3 324.3c-11.4-33.8-11.4-70.4 0-104.2V150H28.9c-38.6 76.9-38.6 167.5 0 244.4l90.4-70.1z"
fill="#fbbc04" />
<path
d="M272.1 107.7c38.8-.6 76.3 14 104.4 40.8l77.7-77.7C405 24.6 339.7-.8 272.1 0 169.2 0 75.1 58 28.9 150l90.4 70.1c21.5-64.5 81.8-112.4 152.8-112.4z"
fill="#ea4335" />
</svg>
</div>
<span>
Sign In with Google
</span>
</button>
</div>
</form>
)
} Is this as a result of having two nested forms? 😄 |
Beta Was this translation helpful? Give feedback.
-
Hey, for anyone stuck with this. I had this error pop up because I had a form inside another form. Thanks to the better hydration error message in Next recently, I was able to get it fixed. |
Beta Was this translation helpful? Give feedback.
-
I get this error as well. I also noticed that it doesn't occur when I do a full reload. My workaround for now is ensuring that when linking to the page with the form, it performs a full reload. It's a dirty solution, but it works for now. |
Beta Was this translation helpful? Give feedback.
-
I got the same error when testing my application. |
Beta Was this translation helpful? Give feedback.
-
Had the same problem in a component with two . When I broke out each form to a own component and imported them it solved the problem. |
Beta Was this translation helpful? Give feedback.
-
I don't know how but removing the |
Beta Was this translation helpful? Give feedback.
-
Having the same problem with ChakraUI modal component **"use client";
import {
Button,
FormControl,
FormLabel,
HStack,
ModalBody,
Text,
useDisclosure,
} from "@chakra-ui/react";
import { getFormProps, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import { invite } from "app/(unauthenticated)/signup/actions";
import { FormInput } from "components/form-input";
import { Modal } from "components/modal";
import { useFormState } from "react-dom";
import { memberInvitationSchema } from "utils/form/schema";
export const MemberSettings = () => {
const { isOpen, onClose } = useDisclosure();
const [lastResult, action] = useFormState(invite, undefined);
const [form, fields] = useForm({
lastResult,
onValidate({ formData }) {
return parseWithZod(formData, { schema: memberInvitationSchema });
},
shouldValidate: "onBlur",
});
return (
<>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalBody pb={6}>
<form {...getFormProps(form)} action={action}>
<FormControl mb={8}>
<FormLabel>Email</FormLabel>
<FormInput placeholder="email" />
</FormControl>
<HStack gap={2} w={"100%"} pb={4}>
<Button
bg={"bg.light.primary"}
color={"text.light.primary"}
borderRadius={"30px"}
border={"none"}
h={"auto"}
w={"100%"}
px={5}
py={3}
key={fields.email.key}
name={fields.email.name}
defaultValue={fields.email.initialValue}
>
<Text lineHeight={"24px"} variant={"large_strong"}>
Add
</Text>
</Button>
<Button
onClick={onClose}
variant={"ghost"}
borderRadius={"30px"}
border={"none"}
h={"auto"}
w={"100%"}
px={5}
py={3}
>
Cancel
</Button>
</HStack>
</form>
</ModalBody>
</Modal>
</>
);
}; Modal works as I expected but the form inside the modal shows Is there any problem using server action with modal or somethink like that? btw, I found similar issue on reddit https://www.reddit.com/r/nextjs/comments/1csf33b/nesting_a_form_using_server_actions_in_a_dialog/?onetap_auto=true&one_tap=true |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
I am getting the same and I have
|
Beta Was this translation helpful? Give feedback.
-
Had this same problem, mine was resolved due fixing a hydration miss match in an unrelated component. |
Beta Was this translation helpful? Give feedback.
-
Had this issue because I was using useFormState and actions inside a form that was inside a Mantine modal triggered by the modal manager, which doesn't support it. Got it working by using a normal modal instead of the modal manager. |
Beta Was this translation helpful? Give feedback.
-
javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you're trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')"
Beta Was this translation helpful? Give feedback.
All reactions