Why rc-form Fields Do Not Disappear: The Importance of Ref Callbacks and clearField in Custom Components
This article explains why fields registered with rc-form may persist and continue to run validation when using functional custom components, analyzes the internal mechanisms of getFieldMeta, clearField, and saveRef, and shows that adding forwardRef support resolves the disappearance and validation issues.
On a sunny morning, a developer receives a bug report that a form submission button does not respond. The form contains a dropdown field A with values A1 and A2 . When A is A1 , fields B , C , and D are shown; when A switches to A2 , fields B , E , and F appear. After filling the visible fields and submitting, the form does not send any request.
Debugging reveals that the validation callback for field D still runs even after the field should have been unmounted, while field C does not trigger validation. The root cause is that D is a custom functional component without proper ref handling, whereas C uses a built‑in component.
The article shows the source code of the demo component, highlighting the use of getFieldDecorator and the conditional rendering of fields based on the value of A . It also reproduces the relevant parts of rc‑form’s source, including getFieldsValue , validateFields , clearField , and the saveRef function that is called when a component is unmounted.
When a component is destroyed, saveRef receives a null component, stores the cleared metadata, and calls fieldsStore.clearField(name) to delete the field and its metadata. This mechanism relies on React’s callback refs, which are invoked with null on unmount.
Because functional components do not have an instance, they must be wrapped with forwardRef to provide a ref callback. Without this, saveRef is never called, the field metadata remains, and the field value persists and its validation rules continue to execute.
Therefore, the solution is to ensure that any custom functional form control used with rc‑form implements forwardRef (or is a class component) so that rc‑form can correctly clear the field via clearField . The article also notes that methods like validateFieldsAndScroll are affected by the same issue.
import { Button, Form, Input, Select } from 'doraemon';
import { createForm } from './form/src';
import MyInput from './MyInput';
const FormItem = Form.Item;
const Option = Select.Option;
const formItemLayout = { labelCol: { span: 4 }, wrapperCol: { span: 20 } };
const Demo = props => {
const { form } = props;
const { getFieldDecorator } = form;
const showA1 = form.getFieldValue('A') === 'A1';
const showA2 = form.getFieldValue('A') === 'A2';
return (
form.validateFields((err, value) => { debugger; })}>校验
{getFieldDecorator('A', {})(
A1
A2
)}
{getFieldDecorator('B', {})(
)}
{showA2 ? (
<>
{getFieldDecorator('E', {})(
)}
{getFieldDecorator('F', {})(
)}
) : showA1 && (
<>
{getFieldDecorator('C', { rules: [{ required: true, message: '请输入C' }] })(
)}
{getFieldDecorator('D', { rules: [{ required: true, message: '请输入D' }] })(
)}
)}
);
};
export default createForm({})(Fengwo);In summary, when using custom form controls with rc‑form, functional components must expose a ref via forwardRef ; otherwise the field metadata is never cleared, leading to lingering values and unwanted validation.
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.