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

React函数组件中使用React.forwardRef()传递ref报错求助

问题解决

错误原因

  1. renderFields类型误用:你把普通渲染函数错误标注为React.ForwardedRef类型,ForwardedRef是用来接收转发后的ref,不是定义普通函数的类型,完全用错了场景。
  2. TextfieldWrapper未转发ref:你给TextfieldWrapper传递了ref={register},但它是普通函数组件,无法直接接收ref,必须用React.forwardRef包裹才能把ref转发到内部的输入元素上。
  3. register用法不当:react-hook-form的register返回的是包含ref、onChange、onBlur的完整对象,只传ref无法让表单正确收集输入值。

修改后的代码

1. 修正TextfieldWrapper组件

import React from 'react';
import TextField from '@mui/material/TextField';

// 调整Fields类型,移除ref字段(ref通过forwardRef传递)
export type Fields = {
    name: string;
    label?: string;
    type?: string;
    id?: string;
};

// 使用forwardRef包裹组件,接收外部传入的ref并转发给内部输入元素
const TextfieldWrapper = React.forwardRef<HTMLInputElement, Fields>((props, ref) => {
  const { name, type, label, ...otherProps } = props;
  
  const configTextfield = {
    name,
    type,
    label,
    ...otherProps,
    fullWidth: true,
    variant: 'outlined',
    inputRef: ref // MUI的TextField用inputRef绑定输入元素的ref,原生input直接用ref
  };

  return <TextField {...configTextfield} />;
});

export default TextfieldWrapper;

2. 修正Form组件

import { useForm } from 'react-hook-form';
import React from 'react';
import TextfieldWrapper from './TextfieldWrapper';

const Form = ({ template }: Template) => {
  const { title, fields } = template;
  const { register, handleSubmit } = useForm();

  const onSubmit = (values: any) => console.log('values', values);

  // 修正renderFields为普通渲染函数,去掉错误的类型标注
  const renderFields = (fields: Fields[]) => {
    return fields?.map((field) => (
      <div key={field.name}>
        {/* 展开register返回的所有属性,包含ref、onChange、onBlur等 */}
        <TextfieldWrapper {...field} {...register(field.name)} />
      </div>
    ));
  };

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        <h4>{title}</h4>
        {renderFields(fields)}
        <button type='submit' className='btn'>Submit</button>
      </form>
    </div>
  );
};

// 修正Template类型定义
export type Template = {
  template: {
    fields: Fields[];
    title?: string;
    onSubmit?: () => void;
  };
  onSubmit?: () => void;
  children?: React.ReactNode;
};

export default Form;

关键修改说明

  • React.forwardRef的作用:让TextfieldWrapper能够接收外部传递的ref,并转发给内部的输入元素,彻底解决"函数组件不能接收ref"的错误提示。
  • register的正确传递:展开register(field.name)的结果,确保react-hook-form能绑定输入元素的所有必要事件和ref,保证表单值能被正确收集。
  • 类型定义修正:移除Fields中的冗余ref字段,修正renderFields的错误类型标注,让类型逻辑更严谨。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 17:10:16