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

React Hook Form+TS遍历渲染MUI输入框校验报错显示异常

问题根因

两个问题都是对象属性访问逻辑写错导致的:

  • 错误提示写死了errors.name,所有输入框都会固定取name字段的校验信息,自然全部显示name的必填提示
  • 写errors.inputName时,JS点语法会默认后面跟的是固定属性名,会去找errors对象上叫「inputName」的属性,不会读取你遍历出来的inputName变量的值;而你定义的FormInputsType里根本没有inputName这个字段,TS就会抛类型错误。
修复方案

核心修改只有一处:把错误提示的取值改成方括号动态访问语法errors[inputName]?.message。
由于你已经把inputName的类型定义为keyof FormInputsType,这种写法TS可以正确推导类型,不会再报类型错误。

附带几个建议优化项:

  • 删掉代码里那段空执行的inputMap.map(({ label, inputName, message }, index) => {}),这段没有任何实际逻辑
  • 遍历列表的key不要用数组index,换成唯一的inputName值更稳定,后续调整inputMap的字段顺序时不会出现输入框内容、状态错位的问题
  • 可以直接用MUI TextField自带的error属性控制错误红框样式、helperText属性展示底部错误提示,不用额外写Typography组件,样式适配更统一。

修复后的核心代码参考:

const {
  formState: { errors },
  handleSubmit,
  control,
} = useForm<FormInputsType>()

<Grid item xs={7}>
  {inputMap.map(({ label, inputName, message }) => (
    <div key={inputName}>
      <Controller 
        name={inputName}
        control={control}
        render={({ field }) => (
          <TextField
            label={label}
            variant="outlined"
            color="primary"
            margin="normal"
            fullWidth
            // 给输入框加错误态样式
            error={Boolean(errors[inputName])}
            // 直接用组件自带属性展示错误提示
            helperText={errors[inputName]?.message}
            {...field}
          />
        )}
        rules={{
          required: {
            value: true,
            message: message,
          },
        }}
      />
      {/* 如果要保留自定义Typography展示错误,就用下面这段替换上面的helperText
      <Typography component="p" color="error">
        {errors[inputName]?.message}
      </Typography> */}
    </div>
  ))}
  <Button
    className={classes.button}
    onClick={handleSubmit(onSubmit)}
    variant="contained"
    fullWidth={true}
  >
    Войти
  </Button>
</Grid>

内容的提问来源于stack exchange,提问作者Миша Иванущенко

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:09:47