diff --git a/packages/ra-core/src/form/FormDataConsumer.tsx b/packages/ra-core/src/form/FormDataConsumer.tsx index 39205f7ec27..7659835765d 100644 --- a/packages/ra-core/src/form/FormDataConsumer.tsx +++ b/packages/ra-core/src/form/FormDataConsumer.tsx @@ -4,6 +4,7 @@ import { useFormContext, FieldValues } from 'react-hook-form'; import get from 'lodash/get'; import { useFormValues } from './useFormValues'; import { useWrappedSource } from '../core'; +import { useEvent } from '../util'; /** * Get the current (edited) value of the record from the form and pass it @@ -67,22 +68,26 @@ export const FormDataConsumerView = < props: Props ) => { const { children, formData, source } = props; - let ret; + const [result, setResult] = React.useState(null); const finalSource = useWrappedSource(source || ''); + const render = useEvent(children); - // Passes an empty string here as we don't have the children sources and we just want to know if we are in an iterator - const matches = ArraySourceRegex.exec(finalSource); + // Getting the result of the children function in a useEffect allows us to keep a stable reference to is + // with useEvent + React.useEffect(() => { + // Passes an empty string here as we don't have the children sources and we just want to know if we are in an iterator + const matches = ArraySourceRegex.exec(finalSource); + // If we have an index, we are in an iterator like component (such as the SimpleFormIterator) + if (matches) { + const scopedFormData = get(formData, matches[0]); + setResult(render({ formData, scopedFormData })); + } else { + setResult(render({ formData })); + } + }, [finalSource, formData, render]); - // If we have an index, we are in an iterator like component (such as the SimpleFormIterator) - if (matches) { - const scopedFormData = get(formData, matches[0]); - ret = children({ formData, scopedFormData }); - } else { - ret = children({ formData }); - } - - return ret === undefined ? null : ret; + return result; }; const ArraySourceRegex = new RegExp(/.+\.\d+$/);