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

如何在Unform中跨文件获取并操作输入组件的值(提交前)

解决方案

Unform 本身提供了官方 API 来操作表单字段,不需要通过 document.getElementById() 或直接跨文件操作组件 ref,以下是具体实现方式:

1. 表单组件内直接获取/修改字段值

利用 formRef 关联的 FormHandles 对象,它提供了 getFieldRef 和 setFieldValue 等方法来操作字段:

修改你的 Login 组件,添加自定义按钮和对应处理函数:

const Login: React.FC = () => {
  const formRef = useRef<FormHandles>(null);

  const handleSubmit = useCallback(
    async (data: SignInFormData) => { 
      try {    
        console.log(data);
      } catch (err) {    
        console.log(err);
      }
    },
    [],
  );

  // 获取CPF字段的值
  const getCpfValue = () => {
    const cpfInputRef = formRef.current?.getFieldRef('cpf') as HTMLInputElement;
    if (cpfInputRef) {
      console.log('当前CPF值:', cpfInputRef.value);
    }
  };

  // 修改CPF字段的值
  const setCpfValue = () => {
    formRef.current?.setFieldValue('cpf', '123.456.789-00');
  };

  return(
    <>
      <Form ref={formRef} onSubmit={handleSubmit} >
        <TextInputInput 
          type='text'  
          id="text" 
          name='cpf'
          placeholder='000.000.000-00' 
        />

        <FormatedTextInput 
          type="password" 
          id='password'
          name='password'
          placeholder='********'
        />
        <Button type='submit'>Entrar</Button>
      </Form>
      {/* 添加自定义操作按钮 */}
      <Button onClick={getCpfValue}>获取CPF值</Button>
      <Button onClick={setCpfValue}>设置默认CPF</Button>
    </>
  )
}

export default Login;

2. 跨文件组件操作表单字段

如果需要在其他文件的组件中操作该表单字段,可通过以下两种方式实现:

方式一:通过 props 传递表单操作方法

在 Login 组件中封装获取/修改字段的方法,传递给跨文件的子组件:

// 跨文件组件 FormActions.tsx
export const FormActions: React.FC<{ getCpf: () => void; setCpf: () => void }> = ({ getCpf, setCpf }) => {
  return (
    <>
      <button onClick={getCpf}>跨文件获取CPF</button>
      <button onClick={setCpf}>跨文件设置CPF</button>
    </>
  );
};

// 在Login组件中引入并传递方法
import { FormActions } from './FormActions';

const Login: React.FC = () => {
  // ... 原有代码

  const getCpfValue = () => {
    const cpfInputRef = formRef.current?.getFieldRef('cpf') as HTMLInputElement;
    if (cpfInputRef) {
      console.log('当前CPF值:', cpfInputRef.value);
    }
  };

  const setCpfValue = () => {
    formRef.current?.setFieldValue('cpf', '123.456.789-00');
  };

  return(
    <>
      <Form ref={formRef} onSubmit={handleSubmit} >
        {/* ... 原有表单内容 */}
      </Form>
      <FormActions getCpf={getCpfValue} setCpf={setCpfValue} />
    </>
  )
}

方式二:使用 React Context 全局管理表单实例

如果需要在多个跨文件组件中操作表单,建议用 Context 封装表单操作能力:

// 创建 FormContext.tsx
import { createContext, useContext, ReactNode } from 'react';
import { FormHandles } from '@unform/core';

type FormContextType = {
  formRef: React.RefObject<FormHandles>;
};

const FormContext = createContext<FormContextType | undefined>(undefined);

export const FormProvider: React.FC<{ children: ReactNode; formRef: React.RefObject<FormHandles> }> = ({ children, formRef }) => {
  return (
    <FormContext.Provider value={{ formRef }}>
      {children}
    </FormContext.Provider>
  );
};

export const useFormContext = () => {
  const context = useContext(FormContext);
  if (!context) {
    throw new Error('useFormContext must be used within a FormProvider');
  }
  return context;
};

// 在Login组件中使用Provider
const Login: React.FC = () => {
  const formRef = useRef<FormHandles>(null);

  // ... 原有代码

  return(
    <FormProvider formRef={formRef}>
      <Form ref={formRef} onSubmit={handleSubmit} >
        {/* ... 原有表单内容 */}
      </Form>
      {/* 跨文件组件可直接放在Provider内部 */}
      <CrossFileComponent />
    </FormProvider>
  )
}

// 跨文件组件 CrossFileComponent.tsx
import { useFormContext } from './FormContext';

export const CrossFileComponent: React.FC = () => {
  const { formRef } = useFormContext();

  const getCpf = () => {
    const cpfInputRef = formRef.current?.getFieldRef('cpf') as HTMLInputElement;
    if (cpfInputRef) {
      console.log('跨文件获取CPF:', cpfInputRef.value);
    }
  };

  const setCpf = () => {
    formRef.current?.setFieldValue('cpf', '999.999.999-99');
  };

  return (
    <>
      <button onClick={getCpf}>跨文件获取CPF值</button>
      <button onClick={setCpf}>跨文件修改CPF值</button>
    </>
  );
};

关键说明

  • getFieldRef(fieldName):通过字段名获取注册的输入元素 ref,直接访问其 value 属性实现取值。
  • setFieldValue(fieldName, value):Unform 官方字段赋值方法,会自动同步表单内部状态,比直接修改 input.value 更可靠。
  • 所有操作基于 Unform 官方 API,无需打破组件封装直接访问子组件 ref,符合 React 组件设计规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:35:12