From e788eaba91842d002847d1d5d5207f57e95f790d Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Mon, 24 Nov 2025 03:31:51 +0000 Subject: [PATCH] Refactor ObjectForm component to implement debounced validation and state updates, improving performance and reducing unnecessary re-renders. --- .../Dashboard/common/ObjectForm.jsx | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/components/Dashboard/common/ObjectForm.jsx b/src/components/Dashboard/common/ObjectForm.jsx index 78fcae1..9dce603 100644 --- a/src/components/Dashboard/common/ObjectForm.jsx +++ b/src/components/Dashboard/common/ObjectForm.jsx @@ -138,24 +138,29 @@ const ObjectForm = forwardRef( return computedValues }, []) - // Validate form on change + // Validate form on change (debounced to avoid heavy work on every keystroke) useEffect(() => { - form - .validateFields({ validateOnly: true }) - .then(() => { - setFormValid(true) - onStateChange({ - formValid: true, - objectData: { ...serverObjectData, ...form.getFieldsValue() } + const timeoutId = setTimeout(() => { + form + .validateFields({ validateOnly: true }) + .then(() => { + setFormValid(true) + onStateChange({ + formValid: true, + objectData: { ...serverObjectData, ...form.getFieldsValue() } + }) }) - }) - .catch(() => { - onStateChange({ - formValid: true, - objectData: { ...serverObjectData, ...form.getFieldsValue() } + .catch(() => { + setFormValid(false) + onStateChange({ + formValid: false, + objectData: { ...serverObjectData, ...form.getFieldsValue() } + }) }) - }) - }, [form, formUpdateValues]) + }, 150) + + return () => clearTimeout(timeoutId) + }, [form, formUpdateValues, onStateChange, serverObjectData]) // Cleanup on unmount useEffect(() => { @@ -252,9 +257,14 @@ const ObjectForm = forwardRef( updateLockEventHandler ]) + // Debounce objectData updates sent to parent to limit re-renders useEffect(() => { - onStateChange({ objectData }) - }, [objectData]) + const timeoutId = setTimeout(() => { + onStateChange({ objectData }) + }, 150) + + return () => clearTimeout(timeoutId) + }, [objectData, onStateChange]) const startEditing = () => { setIsEditing(true) @@ -366,9 +376,18 @@ const ObjectForm = forwardRef( 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) { - 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)