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

使用react-hook-form+shadcnui时组件渲染更新报错求助

React Hook Form Controller 更新组件报错解决方案

问题背景

基于 shadcn/ui、react-hook-form、Zod 和 Next.js 实现文件上传输入组件时,表单校验阶段控制台抛出错误:

Cannot update a component (component) while rendering a different component (Controller)

已定位问题出在字段的 onChange 函数,但未找到替代方案。

核心原因

这个错误的本质是 React 渲染规则限制:不允许在渲染组件 A 的过程中,同步更新另一个组件(或自身)的状态。当你在 Controller 的 render 回调里的 onChange 中同步调用状态更新或表单方法时,就会触发这个冲突。

修复方案

1. 用 useWatch + useEffect 监听字段变化

通过 react-hook-form 的 useWatch 监听字段值变化,再在 useEffect 中执行后续状态更新,完全脱离渲染阶段:

import { useWatch } from "react-hook-form";

// 在组件内添加监听
const fileValue = useWatch({ control, name: "file" });

useEffect(() => {
  if (fileValue?.[0]) { // 文件输入的 value 是 FileList,取第一个文件
    // 这里执行你的状态更新或其他逻辑
    setSelectedFile(fileValue[0]);
  }
}, [fileValue]);

// Controller 部分只处理表单字段更新
<Controller
  name="file"
  control={control}
  render={({ field }) => (
    <Input
      type="file"
      onChange={field.onChange}
      ref={field.ref}
    />
  )}
/>

2. 延迟状态更新(临时方案)

如果必须在 onChange 中处理,用 setTimeout 将状态更新延迟到渲染周期结束后执行:

<Controller
  name="file"
  control={control}
  render={({ field }) => (
    <Input
      type="file"
      onChange={(e) => {
        // 先处理表单字段更新
        field.onChange(e);
        // 延迟执行状态更新,脱离渲染阶段
        setTimeout(() => {
          if (e.target.files?.[0]) {
            setSelectedFile(e.target.files[0]);
          }
        }, 0);
      }}
      ref={field.ref}
    />
  )}
/>

3. 避免在 onChange 中调用表单校验方法

如果报错是因为在 onChange 中同步调用了 trigger 或 setValue,改用 react-hook-form 的内置校验配置,比如在 Zod schema 中定义校验规则,让表单自动触发校验:

// Zod schema 示例
const formSchema = z.object({
  file: z.instanceof(File).refine(
    (file) => file.size <= 1024 * 1024, // 限制1MB
    { message: "文件大小不能超过1MB" }
  )
});

// 表单初始化时传入 schema,自动触发校验
const { control } = useForm({
  resolver: zodResolver(formSchema),
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:22:47