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

调用react-hook-form的reset后,如何让Material-UI字段正确渲染?

解决React Hook Form reset后Material-UI TextField渲染异常的问题

问题根源

  1. 笔误导致number字段初始值错误:number类型的TextField错误使用INITIAL_VALUES.string作为defaultValue,导致初始渲染时输入框显示与字段类型不匹配的空字符串。
  2. defaultValue使用方式错误:React Hook Form的reset方法更新的是表单内部状态,但手动给TextField设置的defaultValue仅在组件首次渲染时生效,后续reset无法同步更新输入框的显示值。

修复步骤

步骤1:修正number字段的defaultValue笔误

将number字段TextField的defaultValue={INITIAL_VALUES.string}改为INITIAL_VALUES.number。

步骤2:将初始值配置到useForm中,移除TextField的defaultValue

在useForm初始化时传入defaultValues参数,替代给每个TextField单独设置defaultValue的方式,确保reset方法能正确同步更新输入框的显示状态。

修改后的完整代码

model.ts(无需修改)

import * as yup from "yup";
import { InferType } from "yup";

export const SCHEMA = yup.object({
  string: yup.string().defined().required("Required").max(100, "Too long"),
  number: yup.number().defined().required("Required").min(1, "Must be positive")
});

export type FormValues = InferType<typeof SCHEMA>;

export const INITIAL_VALUES: FormValues = {
  string: "",
  number: 0
};

表单组件

import { Grid, Box, TextField, Typography, Button } from "@mui/material";
import { useForm } from "react-hook-form";
import { SCHEMA, INITIAL_VALUES, FormValues } from "./model";
import { yupResolver } from "@hookform/resolvers/yup";
import { useEffect, useState } from "react";

export default function EditItemView() {
  const resolver = yupResolver(SCHEMA);
  const [isLoading, setLoading] = useState(false);
  const {
    register,
    handleSubmit,
    reset,
    formState: { errors }
  } = useForm<FormValues>({ 
    resolver, 
    mode: "all",
    defaultValues: INITIAL_VALUES // 将初始值配置到useForm中
  });

  useEffect(() => {
    setLoading(true);
    // 模拟从服务器加载数据
    setTimeout(() => {
      reset({ number: 944, string: "a new string" });
      setLoading(false);
    }, 2000);
  }, [reset]); // 添加reset到依赖数组,避免 useEffect 依赖警告

  return (
    <Box padding={2}>
      <form onSubmit={handleSubmit((formData) => console.log(formData))}>
        <Grid container direction="column" alignItems="stretch" spacing={2}>
          <Grid item>
            <Typography variant="h5">Edit item</Typography>
            {isLoading && <Typography>Loading...</Typography>}
          </Grid>
          <Grid item>
            <TextField
              {...register("string")}
              variant="standard"
              fullWidth
              label="Type a string"
              error={!!errors["string"]}
              helperText={errors["string"]?.message}
            />
          </Grid>
          <Grid item>
            <TextField
              {...register("number")}
              variant="standard"
              fullWidth
              label="Type a positive number"
              type="number" // 添加type属性匹配字段类型
              error={!!errors["number"]}
              helperText={errors["number"]?.message}
            />
          </Grid>
          <Grid item container justifyContent="flex-end">
            <Grid>
              <Button disabled={isLoading} type="submit" variant="contained">
                Submit
              </Button>
            </Grid>
          </Grid>
        </Grid>
      </form>
    </Box>
  );
}

额外优化建议

给number字段的TextField添加type="number"属性,让浏览器提供匹配的数字输入控件,同时减少非数字内容的输入干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:44:50