You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:50:27