SimpleFormIterator causes warning: Each child in a list should have a unique "key" prop -- why?
See original GitHub issueWhat you were expecting: I expected the key prop to be set properly.
What happened instead:
Chrome threw a console error, saying Warning: Each child in a list should have a unique "key" prop.
Steps to reproduce:
Hopefully I won’t have to create a code sandbox for this, I imagine there are not many possible causes for key
property to be left unset.
Let’s say I have a component called MyComponent, defined like this:
interface IMyComponentProps{
choices: Array<{id: number, name: string, children: Array<{id: number, name: string}>}>
source: string;
label?: string;
validate?: ((
value: any,
values: any
) =>
| string
| {
message: string;
args: any;
}) & {
isRequired: boolean;
};
}
export const MyComponent = (props: IMyComponentProps) => {
const { choices, source, validate, label, ...rest } = props;
const form = useForm();
const translate = useTranslate();
return (
<ArrayInput source={source} validate={validate} label={label} {...rest}>
<SimpleFormIterator>
<FormDataConsumer>
{(formDataProps) => {
if (!formDataProps.getSource) {
return null;
}
const { getSource, scopedFormData } = formDataProps;
return (
<div className="some-css-class-name-I-used">
<SelectInput
source={getSource("someId")}
validate={required()}
choices={choices}
onChange={() => form.change(getSource("someOtherId"), null)}
{...rest}
label={translate("resources.common.labels.someId")}
/>
<SelectInput
source={getSource("someOtherId")}
validate={required()}
choices={
choices.find(
(x) =>
x.id === scopedFormData?.someId
)?.children
}
{...rest}
label={translate("resources.common.labels.someOtherId")}
/>
</div>
);
}}
</FormDataConsumer>
</SimpleFormIterator>
</ArrayInput>
);
}
Now put this component into a form (I used a custom form based on your TabbedForm but shouldn’t make any difference, right?)
and put the form, let’s call it MyForm
, into MyCreate
and MyEdit
components. When creating a record, I get no errors when adding multiple children to MyComponent
. However when opening the MyEdit
view, I get the above mentioned error in my console.
I have seen the code of SimpleFormIterator
but the problem isn’t obvious to me.
Call stack trace:
index.js:1 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `SimpleFormIterator`. See https://fb.me/react-warning-keys for more information.
in CSSTransition (created by SimpleFormIterator)
in SimpleFormIterator (at MyComponent.tsx:32)
in div (created by ForwardRef(FormControl))
in ForwardRef(FormControl) (created by WithStyles(ForwardRef(FormControl)))
in WithStyles(ForwardRef(FormControl)) (created by ArrayInput)
in ArrayInput (at MyComponent.tsx:31)
in MyComponent (at MyForm.tsx:69)
in div (created by FormInput)
in FormInput (created by FormTab)
in span (created by FormTab)
in FormTab (at MyForm.tsx:63)
in Route (at MyCustomTabbedForm.tsx:247)
in div (at MyCustomTabbedForm.tsx:238)
in form (at MyCustomTabbedForm.tsx:224)
in TabbedFormView (at MyCustomTabbedForm.tsx:131)
in FormView (created by ReactFinalForm)
in ReactFinalForm (created by FormWithRedirect)
in FormWithRedirect (at MyCustomTabbedForm.tsx:128)
in TabbedForm (at MyForm.tsx:40)
in MyForm (at MyEdit.tsx:11)
in div (created by ForwardRef(Paper))
in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
in WithStyles(ForwardRef(Paper)) (created by ForwardRef(Card))
in ForwardRef(Card) (created by WithStyles(ForwardRef(Card)))
in WithStyles(ForwardRef(Card)) (created by EditView)
in div (created by EditView)
in div (created by EditView)
in EditView (created by Edit)
in Edit (at MyEdit.tsx:10)
in MyEdit (created by WithPermissions)
in WithPermissions (created by Context.Consumer)
in Route (created by ResourceRoutes)
in Switch (created by ResourceRoutes)
in ResourceRoutes (created by Resource)
in Resource (at AdminWrapper.tsx:77)
in Route (created by RoutesWithLayout)
in Switch (created by RoutesWithLayout)
in RoutesWithLayout (created by Context.Consumer)
in div (created by Layout)
in main (created by Layout)
in div (created by Layout)
in div (created by Layout)
in Layout (created by WithStyles(Layout))
in WithStyles(Layout) (created by Context.Consumer)
in withRouter(WithStyles(Layout)) (created by ConnectFunction)
in ConnectFunction (created by LayoutWithTheme)
in ThemeProvider (created by LayoutWithTheme)
in LayoutWithTheme (at Layout.tsx:41)
in Unknown (created by Context.Consumer)
in Route (created by CoreAdminRouter)
in Switch (created by CoreAdminRouter)
in div (created by CoreAdminRouter)
in CoreAdminRouter (created by Context.Consumer)
in Route (created by CoreAdminUI)
in Switch (created by CoreAdminUI)
in CoreAdminUI (created by AdminUI)
in AdminUI (created by Admin)
in Router (created by ConnectedRouter)
in ConnectedRouter (created by Context.Consumer)
in ConnectedRouterWithContext (created by ConnectFunction)
in ConnectFunction (created by CoreAdminContext)
in TranslationProvider (created by CoreAdminContext)
in CoreAdminContext (created by AdminContext)
in AdminContext (created by Admin)
in Admin (at AdminWrapper.tsx:56)
in AdminWrapper (at App.tsx:60)
in Provider (at App.tsx:46)
in App (at src/index.tsx:9)
in StrictMode (at src/index.tsx:8)
Environment
- React-admin version: 3.8.5
- Last version that did not exhibit the issue (if applicable): n/a
- React version: 16.13.1
- Browser: Chrome 85.0.4183.102
- Stack trace (in case of a JS error): above
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:18 (10 by maintainers)
Top GitHub Comments
Well, I should also note that the workaround I posted in the comments above with
useEffect
caused some unforseen consequences when usingreact-final-form
’sform.change()
- in some cases after the aforementioned method is used, the custom iterator I produced above failed to render anything at all… so I’m back to using the originalSimpleFormIterator
and the mystery still remains.Without any way to reproduce it, I have to close this issue. We have to focus on problems that we can actually fix.
Thanks anyway for the report!