React中通过Props传递register实现复用Input组件报错求助
React Hook Form传递register到自定义Input组件报错的排查与解决
报错原因分析
- register调用格式错误:自定义Input组件中,
register第一个参数传入了{name}对象,但react-hook-form要求第一个参数是字段名字符串;同时pattern规则写法错误,不需要嵌套在{pattern}对象中。 - trigger调用参数错误:
trigger需要传入字段名字符串,而非{name}对象。 - 无效的register调用:LoginEn组件中
console.log(register())是空调用register,违反react-hook-form的使用规则,会直接抛出错误。 - 硬编码错误判断:Input组件中className判断写死了
errors.email,无法适配其他字段,组件复用性失效。
修复后的代码
LoginEn.jsx
import React from "react"; import { useForm } from "react-hook-form"; import Input from "../input/Input"; function LoginEn({ login, changLang, lang }) { const { register, handleSubmit, formState: { errors }, reset, trigger, } = useForm(); const onSubmit = (data) => { alert(JSON.stringify(data)); reset(); }; return ( <> <section className="login" id="content"> <div className="login-details"> <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill="#fff" className="svg-left" > <circle cx="-20" cy="-35" r="50" /> </svg> <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill="#fff" className="svg-right" > <circle cx="100" cy="1" r="30" /> </svg> <div className="login-header"> <h2>Login Page</h2> <span>Designed with Adobe XD</span> </div> <div className="login-body"> <div className="row justify-content-center"> <div className="login-leftSide col-lg-6 col-sm-12"> <h3 className="text-start">Logo</h3> <picture> <img className="img-fluid" src={login} alt="" /> </picture> </div> <div className="login-rightSide d-flex flex-column justify-content-center text-start col-lg-6 col-sm-12"> <div className="p-3 watch-responsive"> <div> <div className="d-flex justify-content-between watch-responsive"> <h4 className="d-flex align-items-end"> Welcome Back! </h4> <span className="fw-bold lang" onClick={changLang} > {lang ? "AR" : "EN"} </span> </div> <h6>Login to continue</h6> </div> <form onSubmit={handleSubmit(onSubmit)} method="POST"> <div className="login-inputs d-flex flex-column gap-2 mb-3 "> <div className="input-field d-flex justify-content-center align-items-center"> <span className="icon-user"></span> <Input errors={errors} register={register} trigger={trigger} name="email" placeholder="Write your Email" pattern={ /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/i } ></Input> </div> <span className="errorMsg"> {errors.email?.type === "required" && "email is required"} {errors.email?.type === "pattern" && "Entered a wrong format"} </span> </div> <button type="submit">Login</button> </form> </div> </div> </div> </div> </div> </section> </> ); } export default LoginEn;
Input.jsx
import React from "react"; const Input = ({ errors, register, trigger, name, placeholder, pattern }) => { return ( <input className={errors[name] ? "border border-danger" : ""} placeholder={placeholder} {...register(name, { required: true, pattern: pattern, })} onKeyUp={() => { trigger(name); }} /> ); }; export default Input;
额外说明
- 移除了LoginEn中无效的
console.log(register())调用,避免不必要的报错。 - 修正了邮箱正则表达式中的
.为\.,确保匹配域名中的点号。 - Input组件的className判断改为动态的
errors[name],适配任意字段的错误状态,保证组件复用性。
内容的提问来源于stack exchange,提问作者Mario Magdy
相关产品推荐
相关产品推荐

