使用 antd3 的 Form 进行开发时经常需要自定义一些组件,之前都是使用类组件实现,没有问题,但是自从 hooks 发布后,目前开发基本转向了函数组件,但是 Form getFieldDecorator 传入函数组件控制台会出现错误提示。
假如我们定义如下的组件:
import React, {
useRef } from "react";
import {
Form, Input } from 'antd';
const TextInput = () => {
return <Input />
}
function TextInputWithFocusButton(props) {
return (
<Form.Item label="input">
{
props.form.getFieldDecorator('inputValue')(
<TextInput />
)}
</Form.Item>
);
}
export default Form.create()(TextInputWithFocusButton);
控制台会出现下面的错误提示:
该提示是 react 内部的校验提示,通过查看源码,发现 react 在测试环境中会对函数组件进行校验,如果函数组件上存在 ref,便会出现该提示,具体源码参看 ReactFiberBeginWork.new.js 。
这时我们会感到很疑惑, 明明没有传递 ref 属性,怎么会有这个提示?
初步猜想是 getFieldDecorator 捣的鬼,这个函数是一个 HOC,会不会是它给我们的函数组件上添加了 ref 属性?通过查看源码,我们发现其内部确实会生成一个 inputProps 对象并挂载 ref 属性,具体源码参看 createBaseForm.js。
也就是说只要被 getFieldDecorator 包裹后的组件,都会被添加一个 ref 属性,通过 debug 验证我们的猜想
那么如何来解决这个问题,答案很简单,使用 React.createRef 包裹一下即可:
import React, {
useRef } from "react";
import {
Form, Input } from 'antd';
const TextInput = React.forwardRef((props, ref) => {
return <Input />
})
function TextInputWithFocusButton(props) {
return (
<Form.Item label="input">
{
props.form.getFieldDecorator('inputValue')(
<TextInput />
)}
</