React Hook Form中e.preventDefault()失效,表单提交仍刷新页面
解决React Hook Form中表单提交后页面刷新的问题
你的问题出在两个核心错误上:
- 参数传递顺序错误:
handleSubmit的回调函数第一个参数是表单数据data,第二个才是提交事件e,但你在调用时把事件当成数据传给了handleAddNewItem,导致e始终为undefined,preventDefault()根本没有执行。 - onSubmit写法错误:用箭头函数包裹
handleSubmit阻断了原生事件的传递,React Hook Form无法把提交事件传递到你的处理函数中。
修复步骤:
- 保持
handleAddNewItem的参数顺序正确(先数据,后事件):
function handleAddNewItem(data: Record<string, any>, e?: React.FormEvent<HTMLFormElement>) { // 注:React Hook Form的handleSubmit默认已经阻止了默认提交行为,这行可省略;若有额外事件处理需求可保留 e?.preventDefault(); console.log(data); }
- 修正form的
onSubmit属性,直接传递handleSubmit(handleAddNewItem):
<form onSubmit={handleSubmit(handleAddNewItem)} className="space-y-8">
完整修复后的代码:
import { useForm } from "react-hook-form" import { motion } from "framer-motion" function NewItemModal() { const { register, handleSubmit } = useForm() function handleAddNewItem(data: Record<string, any>, e?: React.FormEvent<HTMLFormElement>) { e?.preventDefault() console.log(data) } return ( <> <form onSubmit={handleSubmit(handleAddNewItem)} className="space-y-8"> <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 place-items-center gap-y-6'> <label className='space-y-1'> <h4>ID:</h4> <motion.input whileFocus={{ borderColor: '#FF9400' }} type="text" className='border border-raisin rounded indent-1 outline-none' {...register('item_id')} /> </label> <div></div> <label className='space-y-1'> <h4>Nome:</h4> <motion.input whileFocus={{ borderColor: '#FF9400' }} type="text" className='border border-raisin rounded indent-1 outline-none' {...register('name')} /> </label> <label className='space-y-1'> <h4>Condição:</h4> <motion.input whileFocus={{ borderColor: '#FF9400' }} type="text" className='border border-raisin rounded indent-1 outline-none' {...register('condition')} /> </label> <label className='space-y-1'> <h4>Marca:</h4> <motion.input whileFocus={{ borderColor: '#FF9400' }} type="text" className='border border-raisin rounded indent-1 outline-none' {...register('brand')} /> </label> <label className='space-y-1'> <h4>Setor:</h4> <motion.input whileFocus={{ borderColor: '#FF9400' }} type="text" className='border border-raisin rounded indent-1 outline-none' {...register('sector')} /> </label> <label className='space-y-1'> <h4>Comodatário:</h4> <motion.input whileFocus={{ borderColor: '#FF9400' }} type="text" className='border border-raisin rounded indent-1 outline-none' {...register('borrower')} /> </label> <label className='space-y-1'> <h4>Data:</h4> <motion.input whileFocus={{ borderColor: '#FF9400' }} type="text" className='border border-raisin rounded indent-1 outline-none' {...register('borrowerDate')} /> </label> </div> <div className='px-4 py-1 space-y-6 flex flex-col'> <label className='space-y-3 flex flex-col items-center'> <h4 className="self-start">Descrição:</h4> <motion.textarea whileFocus={{ borderColor: '#FF9400' }} className='p-2 w-full h-56 outline-none border border-raisin rounded text-sm' {...register('description')} ></motion.textarea> </label> <div className='flex justify-end'> <motion.button whileHover={{ scale: 1.03 }} type="submit" className="bg-princeton px-2 w-20 h-8 rounded border-2 border-raisin"> Enviar </motion.button> </div> </div> </form> </> ) } export default NewItemModal
额外提示:原代码中的textarea未通过register注册,表单提交时不会包含它的值,建议添加{...register('description')}。
内容的提问来源于stack exchange,提问作者Bruno Bispo
相关产品推荐
相关产品推荐

