Stop Unnecessary Re-Renders in Ant Design Forms with shouldUpdate
Use Ant Design Form.Item shouldUpdate to skip re-renders when unrelated form values change, keeping complex forms responsive.
01 Sept 2025, 13:00 UTC

You open an Ant Design form with a country selector and several dependent fields—state, city, postal code, and tax ID. The user types one character into the city input, and every Form.Item connected to the form re-renders. The input lags, expensive child components run again, and the form feels sluggish even though only one field changed.
The useful takeaway is that you do not need to move state out of Ant Design or replace the form library. Ant Design's Form.Item accepts a shouldUpdate prop that acts as a render gate. You can tell Ant Design to re-render a field only when the values that actually matter to it change, while keeping dependencies for validation triggers.
How the Ant Design form store notifies fields
Ant Design's Form maintains an internal form store: a central object holding the current value of every field registered with a name prop. Each Form.Item subscribes to that store. When any value changes, Ant Design checks which subscribers should update. By default, an item re-renders whenever any form value changes, not just its own. In a long form, that default behavior turns every keystroke into a full-form render cycle.
Using shouldUpdate as a render gate
shouldUpdate receives the previous form values and the current form values. Return false to skip the re-render for that item when the change originated elsewhere in the form. Return true when the item needs to reflect the new values.
import { Form, Input, Select, Button } from 'antd';
const ShippingForm = () => {
const [form] = Form.useForm();
return (
console.log(values)}>
prev.country !== current.country}
>
Save
);
};
In this example, typing in city does not re-render the state field because state only cares about country. The city item still updates because its own value changed.
Worked example: dependent validation without render storms
Validation and rendering are separate concerns in Ant Design. Use dependencies to re-run validation when a controlling field changes, and use shouldUpdate to keep the render blast radius small.
const usPostalRule = {
validator: (_: unknown, value: string) => {
const country = form.getFieldValue('country');
if (country === 'US' && !/^\d{5}(-\d{4})?$/.test(value || '')) {
return Promise.reject(new Error('Enter a valid US ZIP code'));
}
return Promise.resolve();
},
};
// ...
prev.postalCode !== current.postalCode || prev.country !== current.country
}
>
Changing the country dropdown re-runs the postal code validator because of dependencies. The item only re-renders, though, when the postal code or country actually changes, so unrelated fields stay untouched.
Limitation: stale conditional UI
shouldUpdate controls rendering, not validation logic. If you render helper text, icons, or conditional fields based on another field's value, returning false can leave that UI stale until the item re-renders for another reason. Keep display logic inside the item, move it to a memoized child component, or accept the occasional extra render for UI that must stay in sync.
Verification
- Open React DevTools and enable "Highlight updates when components render."
- Type in the city field. Only the city
Form.Itemand its input should flash. - Change the country dropdown. The postal code field should re-render and show validation if the value is invalid.
- If unrelated fields flash, tighten the
shouldUpdatecomparison or extract expensive UI intoReact.memochildren.
Closing
Ant Design's form store removes manual useState boilerplate, but its default subscription model can over-render complex forms. Use shouldUpdate as a targeted optimization for fields that do not need to react to every sibling, and reserve dependencies for validation logic. Measure with React DevTools before and after to confirm the render blast radius actually shrank.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.