Refactor ObjectForm component to implement debounced validation and state updates, improving performance and reducing unnecessary re-renders.

This commit is contained in:
Tom Butcher 2025-11-24 03:31:51 +00:00
parent 6af832afe5
commit e788eaba91

View File

@ -138,8 +138,9 @@ const ObjectForm = forwardRef(
return computedValues return computedValues
}, []) }, [])
// Validate form on change // Validate form on change (debounced to avoid heavy work on every keystroke)
useEffect(() => { useEffect(() => {
const timeoutId = setTimeout(() => {
form form
.validateFields({ validateOnly: true }) .validateFields({ validateOnly: true })
.then(() => { .then(() => {
@ -150,12 +151,16 @@ const ObjectForm = forwardRef(
}) })
}) })
.catch(() => { .catch(() => {
setFormValid(false)
onStateChange({ onStateChange({
formValid: true, formValid: false,
objectData: { ...serverObjectData, ...form.getFieldsValue() } objectData: { ...serverObjectData, ...form.getFieldsValue() }
}) })
}) })
}, [form, formUpdateValues]) }, 150)
return () => clearTimeout(timeoutId)
}, [form, formUpdateValues, onStateChange, serverObjectData])
// Cleanup on unmount // Cleanup on unmount
useEffect(() => { useEffect(() => {
@ -252,9 +257,14 @@ const ObjectForm = forwardRef(
updateLockEventHandler updateLockEventHandler
]) ])
// Debounce objectData updates sent to parent to limit re-renders
useEffect(() => { useEffect(() => {
const timeoutId = setTimeout(() => {
onStateChange({ objectData }) onStateChange({ objectData })
}, [objectData]) }, 150)
return () => clearTimeout(timeoutId)
}, [objectData, onStateChange])
const startEditing = () => { const startEditing = () => {
setIsEditing(true) setIsEditing(true)
@ -366,10 +376,19 @@ const ObjectForm = forwardRef(
model model
) )
// Update form with computed values if any were calculated // Update form with computed values if any were calculated and they changed
if (Object.keys(computedValues).length > 0) { if (Object.keys(computedValues).length > 0) {
const currentComputedValues = form.getFieldsValue(
Object.keys(computedValues)
)
const hasDiff = Object.keys(computedValues).some(
(key) => currentComputedValues[key] !== computedValues[key]
)
if (hasDiff) {
form.setFieldsValue(computedValues) form.setFieldsValue(computedValues)
} }
}
// Merge all values (user input + computed values) // Merge all values (user input + computed values)
const allValues = { ...values, ...computedValues } const allValues = { ...values, ...computedValues }