使用react-hook-form提交表单后,email和password值返回undefined
React Hook Form 提交后表单值为undefined的解决方法
问题描述
使用ReactJS、TypeScript和styled-components开发登录页面,通过react-hook-form处理表单逻辑,表单仅包含邮箱和密码输入字段。提交表单后console.log输出的email和password均为undefined,浏览器控制台无报错信息。
核心原因
你给两个InputField都传递了同一个外部ref,覆盖了react-hook-form通过register生成的内部ref,导致表单无法捕获输入框的值。react-hook-form的register方法会自动为输入框绑定用于跟踪值的ref,手动传递外部ref会破坏这一机制。
解决方案
方案1:移除不必要的外部ref
如果不需要父组件控制输入框的ref,直接删除InputField上的ref={ref}属性即可:
import React from "react"; import { useForm, SubmitHandler } from "react-hook-form"; import { Form, TitleSecondary } from "./Form.style"; import { Button } from "../Button/Button"; import { InputContainer, InputLabel, InputField } from "./Form.style"; interface IForm { email: string; password: string; } // 移除forwardRef,因为不需要传递外部ref export const FormLogin = () => { const { register, handleSubmit } = useForm<IForm>(); const onSubmit: SubmitHandler<IForm> = (data) => console.log(data); return ( <Form onSubmit={handleSubmit(onSubmit)}> <TitleSecondary>Login</TitleSecondary> <InputContainer> <InputLabel htmlFor="email">Email</InputLabel> <InputField {...register("email")} id="email" type="email" placeholder="" required /> </InputContainer> <InputContainer> <InputLabel htmlFor="password">Password</InputLabel> <InputField {...register("password")} id="password" type="password" placeholder="mail@example.com" required /> </InputContainer> <Button /> </Form> ) }
方案2:为每个输入框分配独立的ref
如果确实需要父组件控制输入框(比如邮箱输入框自动聚焦),给每个输入框分配独立的ref,避免覆盖react-hook-form的内部ref:
import React, { useRef } from "react"; import { useForm, SubmitHandler } from "react-hook-form"; import { Form, TitleSecondary } from "./Form.style"; import { Button } from "../Button/Button"; import { InputContainer, InputLabel, InputField } from "./Form.style"; interface IForm { email: string; password: string; } export const FormLogin = React.forwardRef<HTMLInputElement>((props, ref) => { const { register, handleSubmit } = useForm<IForm>(); // 为密码输入框创建独立的ref const passwordRef = useRef<HTMLInputElement>(null); const onSubmit: SubmitHandler<IForm> = (data) => console.log(data); return ( <Form onSubmit={handleSubmit(onSubmit)}> <TitleSecondary>Login</TitleSecondary> <InputContainer> <InputLabel htmlFor="email">Email</InputLabel> <InputField {...register("email")} id="email" type="email" placeholder="" ref={ref} // 仅给邮箱输入框传递外部ref required /> </InputContainer> <InputContainer> <InputLabel htmlFor="password">Password</InputLabel> <InputField {...register("password")} id="password" type="password" placeholder="mail@example.com" ref={passwordRef} // 密码输入框使用独立ref required /> </InputContainer> <Button /> </Form> ) })
补充说明
register方法返回的对象包含react-hook-form用于跟踪输入值的ref,手动覆盖这个ref会导致表单无法关联输入框的内容。- 你的代码中输入框的
id与register的字段名保持一致,这部分是正确的,无需修改。
内容的提问来源于stack exchange,提问作者Jenyffer Bastos
相关产品推荐
相关产品推荐

