如何使用react-hook-form实现按注册类型切换表单字段?
使用react-hook-form实现动态切换的注册表单
步骤1:安装依赖
确保你的项目中已安装react-hook-form:
npm install react-hook-form # 或 yarn add react-hook-form
步骤2:实现动态表单逻辑
核心是利用watch API监听注册类型的选择,实时渲染对应表单字段。以下是完整组件示例:
import { useForm } from "react-hook-form"; const DynamicRegistrationForm = () => { // 初始化表单,默认设置注册类型为客户 const { register, watch, handleSubmit, formState: { errors }, reset } = useForm({ defaultValues: { registerType: "customer" } }); // 监听注册类型字段的变化 const selectedType = watch("registerType"); // 提交处理函数 const onSubmit = (data) => { // 根据注册类型处理提交逻辑 if (selectedType === "customer") { console.log("提交客户数据:", data); // 这里可调用客户注册接口 } else { console.log("提交产品数据:", data); // 这里可调用产品注册接口 } }; return ( <form onSubmit={handleSubmit(onSubmit)}> {/* 注册类型下拉选择 */} <div> <label>注册类型:</label> <select {...register("registerType", { required: "请选择注册类型" })}> <option value="customer">客户</option> <option value="product">产品</option> </select> {errors.registerType && <p style={{ color: "red" }}>{errors.registerType.message}</p>} </div> {/* 渲染客户注册表单 */} {selectedType === "customer" && ( <div className="customer-form"> <h3>客户注册信息</h3> <div> <label>姓名:</label> <input {...register("customerName", { required: "请输入姓名" })} placeholder="请输入姓名" /> {errors.customerName && <p style={{ color: "red" }}>{errors.customerName.message}</p>} </div> <div> <label>邮箱:</label> <input {...register("customerEmail", { required: "请输入邮箱", pattern: { value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: "请输入有效的邮箱地址" } })} placeholder="请输入邮箱" /> {errors.customerEmail && <p style={{ color: "red" }}>{errors.customerEmail.message}</p>} </div> <div> <label>联系电话:</label> <input {...register("customerPhone", { required: "请输入联系电话" })} placeholder="请输入联系电话" /> {errors.customerPhone && <p style={{ color: "red" }}>{errors.customerPhone.message}</p>} </div> </div> )} {/* 渲染产品注册表单 */} {selectedType === "product" && ( <div className="product-form"> <h3>产品注册信息</h3> <div> <label>产品名称:</label> <input {...register("productName", { required: "请输入产品名称" })} placeholder="请输入产品名称" /> {errors.productName && <p style={{ color: "red" }}>{errors.productName.message}</p>} </div> <div> <label>产品SKU:</label> <input {...register("productSKU", { required: "请输入产品SKU" })} placeholder="请输入产品SKU" /> {errors.productSKU && <p style={{ color: "red" }}>{errors.productSKU.message}</p>} </div> <div> <label>产品价格:</label> <input type="number" {...register("productPrice", { required: "请输入产品价格", min: { value: 0, message: "价格不能为负数" } })} placeholder="请输入产品价格" /> {errors.productPrice && <p style={{ color: "red" }}>{errors.productPrice.message}</p>} </div> </div> )} <button type="submit">提交注册</button> </form> ); }; export default DynamicRegistrationForm;
关键说明
watch("registerType"):实时监听下拉框选择值,触发表单区段切换register:统一注册所有表单字段,同时配置校验规则,错误信息通过errors对象获取- 条件渲染:通过
selectedType判断渲染对应表单,确保字段仅在需要时加载 - 提交逻辑:在
onSubmit中根据类型区分处理提交数据
扩展建议
- 若字段较多,可将客户/产品表单拆分为独立组件(如
CustomerForm、ProductForm),提升复用性 - 切换类型时可调用
reset清空对应字段,避免残留输入:import { useEffect } from "react"; useEffect(() => { reset({ registerType: selectedType }); }, [selectedType, reset]); - 可添加更复杂的校验规则,比如手机号格式、SKU唯一性校验等
内容的提问来源于stack exchange,提问作者Allan
相关产品推荐
相关产品推荐

