Array input issue when removing and reinserting element
See original GitHub issueBug
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
Issue Analytics
- State:
- Created a year ago
- Reactions:6
- Comments:6 (3 by maintainers)
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