Array input issue when removing and reinserting element
Bug
The bug happens when I have inside a SimpleFormIterator a React.FC or a FormDataConsumer.
In those cases if I have defaults they are not applied and if there is a record the informations shown does not respect the form state.
To reproduce
To reproduce the bug use this CODESANDBOX Enter into the edit of the only comment present here delete this from the form. Then reinsert it. The form seems filled because you can see the numbers but if you press submit the validation error appears informing you that the form is not filled.
Result of bug:

Problem found
The screen below is the SimpleFormIterator addField function, in this function if I have a form data consumer or any other React.FC that have not source nor the default value on the SimpleFormIterator level the default returned is {undefined: ""}
This causes that react admin renders the array value from the record thinking that the form is filling with the record, showing a wrong value from record and not from the form state.

Drity workaround to partially solve this issue
type Props<T> = SimpleFormIteratorProps & {
defaultValue?: { [TKey in keyof T]: T[TKey] }
}
/**
* This component is used because react admin cannot handle default values for React.FC children of
* the standard SimpleFormIterator. For those elements the native one takes the default from the record but it
* does not update the record with like result having the field filled but with an empty form.
*
* @param SimpleFormIteratorProps all the props of the SimpleFormIterator
* @param defaultValue this one is used when a new element is added
* @return the standard SimpleFormIterator with the ability to add a default value to each element of the array
*/
const KSimpleFormIterator = <T extends any>({
children,
source,
defaultValue,
...rest
}: Props<T>) => {
// this source is automatically passed by the array input
if (!source) throw new Error('KSimpleFormIterator: source is required')
// we are going to perform a watch on the the array input values
const arrayValue = useWatch({ name: source }) as Array<any>
// we memorize the array input values
const [value, setValue] = useState(arrayValue)
// this hook is used to manipulate the ReactAdmin array input form state
const { append, remove } = useArrayInput({ ...rest })
console.log('aaa', {
children: Children.toArray(children),
})
// if an element was added
if (value.length < arrayValue.length) {
// remove the last added element with wrong default value
remove(arrayValue.length - 1)
// set the default value with the correct one appending it like last element of the array
append(defaultValue)
// updates the cached value inside the component
setValue(arrayValue)
} else if (value.length > arrayValue.length) {
// updates the cached value inside the component
setValue(arrayValue)
}
return (
<SimpleFormIterator {...rest} source={source}>
{children}
</SimpleFormIterator>
)
}
export default KSimpleFormIterator
Thank you for reporting this. Your codesandbox doesn't seem to be functional. Can you fix it?
Same happens to me!
@WiXSL codesandbox gives error but if you take its url ( https://gzwqfp.sse.codesandbox.io/#/comments ) you can reproduce it
@WiXSL try to enter in the link above that is the one of the deployed version where you can reproduce it.
Thanks, seems like a bug. I have to investigate further.
UPDATE: I can reproduce it on stackblitz and codesandbox but not locally. I'll keep investigating
UPDATE: I can reproduce it on stackblitz and codesandbox but not locally. I'll keep investigating
@WiXSL I could reproduce it locally through these steps:
- (codesandbox) File > export to ZIP
- extract and
(p)npm install -
(p)npm dev
If I can help to reproduce, please write me!
