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

如何用Zod根据其他字段值动态设置表单必填字段?

Zod + react-hook-form 实现条件必填字段

你可以利用Zod的when方法,根据cli_persona_natural字段的值,动态设置cli_nombres、cli_apellido_paterno和cli_apellido_materno的必填规则,具体实现如下:

调整后的表单Schema

import z from "zod";

const formSchema = z.object({
    cli_rut: z.string(),
    cli_persona_natural: z.enum(["SI", "NO"]),
    // 条件控制姓名为必填(当cli_persona_natural为"SI"时)
    cli_nombres: z.string().when("cli_persona_natural", {
        is: "SI",
        then: (schema) => schema.required("姓名为必填项"),
        otherwise: (schema) => schema.optional(),
    }),
    // 条件控制父姓为必填
    cli_apellido_paterno: z.string().when("cli_persona_natural", {
        is: "SI",
        then: (schema) => schema.required("父姓为必填项"),
        otherwise: (schema) => schema.optional(),
    }),
    // 条件控制母姓为必填
    cli_apellido_materno: z.string().when("cli_persona_natural", {
        is: "SI",
        then: (schema) => schema.required("母姓为必填项"),
        otherwise: (schema) => schema.optional(),
    }),
    cli_razon_social: z.string().optional(),
    cli_estado: z.string().default("ACTIVO").optional(),
});

和react-hook-form结合使用

需要借助@hookform/resolvers/zod提供的解析器,将Zod Schema和react-hook-form关联:

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

function YourFormComponent() {
    const { register, handleSubmit, formState: { errors } } = useForm({
        resolver: zodResolver(formSchema),
        defaultValues: {
            cli_estado: "ACTIVO"
        }
    });

    const onSubmit = (formData) => {
        // 处理表单提交逻辑
        console.log(formData);
    };

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            {/* RUT输入框 */}
            <div>
                <label>RUT</label>
                <input {...register("cli_rut")} />
                {errors.cli_rut && <span className="error">{errors.cli_rut.message}</span>}
            </div>

            {/* 自然人/法人选择 */}
            <div>
                <label>是否为自然人</label>
                <select {...register("cli_persona_natural")}>
                    <option value="SI">SI</option>
                    <option value="NO">NO</option>
                </select>
            </div>

            {/* 姓名输入框 */}
            <div>
                <label>姓名</label>
                <input {...register("cli_nombres")} />
                {errors.cli_nombres && <span className="error">{errors.cli_nombres.message}</span>}
            </div>

            {/* 父姓输入框 */}
            <div>
                <label>父姓</label>
                <input {...register("cli_apellido_paterno")} />
                {errors.cli_apellido_paterno && <span className="error">{errors.cli_apellido_paterno.message}</span>}
            </div>

            {/* 母姓输入框 */}
            <div>
                <label>母姓</label>
                <input {...register("cli_apellido_materno")} />
                {errors.cli_apellido_materno && <span className="error">{errors.cli_apellido_materno.message}</span>}
            </div>

            {/* 公司名称输入框 */}
            <div>
                <label>公司名称</label>
                <input {...register("cli_razon_social")} />
            </div>

            <button type="submit">提交</button>
        </form>
    );
}

原理说明

  • z.when方法允许你基于其他字段的值,为当前字段应用不同的验证规则。
  • 当cli_persona_natural的值为"SI"时,对应的姓名、父姓、母姓字段会被设为必填,并显示自定义错误提示;选择"NO"时,这些字段保持可选状态。
  • react-hook-form会通过zodResolver自动同步Zod的验证规则,在表单提交或字段值变化时触发验证。

内容的提问来源于stack exchange,提问作者Enzo Briones

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:27:06