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

如何在动态构建Yup Schema完成后条件式调用useForm?

动态构建Yup Schema配合useForm的正确姿势

核心问题拆解

你现在卡在两个关键点:一是违反React Hook调用规则(不能在条件分支后调用Hook),二是Schema更新后useForm校验逻辑的同步问题,还有null传入resolver直接报错的坑。

直接可行的解决方案

把useForm移到组件顶层,给resolver加兜底逻辑,再通过监听Schema变化重置表单:

function myHook() {
  const [mySchema, setMySchema] = useState<AnyObjectSchema | null>(null);

  useEffect(() => {
    // 替换为实际后端请求逻辑
    const fetchSchema = async () => {
      const res = await fetch('/api/form-definition');
      const schemaConfig = await res.json();
      // 根据后端配置构建Yup Schema,示例逻辑按需调整
      const newSchema = yup.object().shape(schemaConfig);
      setMySchema(newSchema);
    };
    fetchSchema();
  }, []);

  // 顶层无条件调用useForm,解决Hook规则问题
  const { handleSubmit, register, reset } = useForm({
    // 兜底:Schema未加载时返回空校验,避免报错
    resolver: mySchema ? yupResolver(mySchema) : () => Promise.resolve({ values: {}, errors: {} }),
    defaultValues: {} // 按需设置表单默认值
  });

  // 当Schema更新时,重置表单让新校验规则生效
  useEffect(() => {
    if (mySchema) {
      reset();
    }
  }, [mySchema, reset]);

  if (!mySchema) {
    return <SkeletonForm />;
  }

  return <TheFormGoesHere register={register} handleSubmit={handleSubmit} />;
}

关键细节说明

  • 兜底Resolver:没拿到Schema时,返回一个永远成功的校验结果,既避免yupResolver因null报错,也符合useForm的参数要求。
  • Schema更新同步:useForm的resolver变化不会自动触发重新校验,所以用useEffect监听mySchema变化,调用reset重置表单,强制应用新规则。
  • Hook合规性:useForm在组件最顶层调用,完全符合React Hook的调用规则,不会出现控制台警告。

额外小技巧

  • 骨架屏阶段把表单提交按钮设为禁用状态,防止用户误操作。
  • 构建Schema时加try-catch,避免后端返回的配置异常导致页面崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:40:55