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,24 +138,29 @@ 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(() => {
form const timeoutId = setTimeout(() => {
.validateFields({ validateOnly: true }) form
.then(() => { .validateFields({ validateOnly: true })
setFormValid(true) .then(() => {
onStateChange({ setFormValid(true)
formValid: true, onStateChange({
objectData: { ...serverObjectData, ...form.getFieldsValue() } formValid: true,
objectData: { ...serverObjectData, ...form.getFieldsValue() }
})
}) })
}) .catch(() => {
.catch(() => { setFormValid(false)
onStateChange({ onStateChange({
formValid: true, formValid: false,
objectData: { ...serverObjectData, ...form.getFieldsValue() } objectData: { ...serverObjectData, ...form.getFieldsValue() }
})
}) })
}) }, 150)
}, [form, formUpdateValues])
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(() => {
onStateChange({ objectData }) const timeoutId = setTimeout(() => {
}, [objectData]) onStateChange({ objectData })
}, 150)
return () => clearTimeout(timeoutId)
}, [objectData, onStateChange])
const startEditing = () => { const startEditing = () => {
setIsEditing(true) setIsEditing(true)
@ -366,9 +376,18 @@ 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) {
form.setFieldsValue(computedValues) const currentComputedValues = form.getFieldsValue(
Object.keys(computedValues)
)
const hasDiff = Object.keys(computedValues).some(
(key) => currentComputedValues[key] !== computedValues[key]
)
if (hasDiff) {
form.setFieldsValue(computedValues)
}
} }
// Merge all values (user input + computed values) // Merge all values (user input + computed values)