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

react-hook-form通过ref改值后触发MUI TextField重渲染的方法

问题场景
  • 使用 Material UI 的 TextField 组件搭配 react-hook-form 实现表单控制,表单初始传入的 defaultValues 为空
  • 页面加载后发起API请求获取用户账户数据,表单初始渲染完成后,defaultValues 会随接口返回数据更新
  • 表单逻辑中使用 useEffect 钩子,在接收到新的填充数据(包括接口返回初始数据、后续数据刷新场景)时调用 reset() 方法重置表单值
  • 异常表现:上述逻辑在多数场景运行正常,但当初始 defaultValues 为空时会出现样式异常:表单值虽然被正确填入输入框,但输入框标签不会上浮到边框位置,占位符也不会消失,只有手动编辑字段后标签样式才会恢复正常
问题根因

react-hook-form 默认通过 ref 直接操作DOM设置输入框值,这个过程不会触发 MUI TextField 组件的React重渲染,导致组件无法识别输入框已有值,无法自动调整标签浮动状态。

修复方案

最稳妥的方案是使用 react-hook-form 官方提供的 Controller 组件包裹 TextField,将字段转为受控模式,让表单值通过props传递给组件,值变化时自然触发组件重渲染,MUI就能正确识别值状态更新样式。

修复步骤

  1. 从 react-hook-form 中额外导入 Controller,并在 useForm 返回值中解构出 control 属性
  2. 替换原来直接通过 register 绑定字段的写法,用 Controller 包裹 TextField,通过 render 属性把表单字段的属性透传给组件

修复后的核心代码如下:

import React, { useEffect } from 'react'
import { useForm, Controller } from 'react-hook-form'
import * as Yup from 'yup'

import { yupResolver } from '@hookform/resolvers/yup'
import Button from '@material-ui/core/Button'
import BaseTextField from '@material-ui/core/TextField'

const schema = Yup.object().shape({
  firstName: Yup.string(),
})

const TextField = React.forwardRef((props, ref) => (
  <BaseTextField {...props} inputRef={ref} />
))

const MyForm = ({ data, mutate, submitting }) => {
  // 额外解构出control
  const { control, handleSubmit, reset } = useForm({
    defaultValues: data,
    resolver: schema ? yupResolver(schema) : undefined,
  })

  useEffect(() => {
    reset(data)
  }, [reset, data])

  return (
    <form onSubmit={handleSubmit(mutate)}>
      {/* 使用Controller包裹字段 */}
      <Controller
        name="firstName"
        control={control}
        render={({ field }) => (
          <TextField
            {...field}
            disabled={submitting}
            fullWidth
            id="firstName"
            label="First Name"
            margin="normal"
            variant="outlined"
          />
        )}
      />
      <Button
        variant="contained"
        disabled={submitting}
        color="primary"
        type="submit"
      >
        Save
      </Button>
    </form>
  )
}

调整后reset()更新表单值时,值会通过props传递给TextField,组件能正确感知值的变化,自动触发标签上浮的样式逻辑,不会再出现样式错位问题。这也是react-hook-form官方推荐的对接第三方UI组件库的标准方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:01:29