简体   繁体   中英

Warning: flattenChildren(…): Encountered two children with the same key in reactjs

I'm using Tabs from Material UI where I'm displaying a List component filtered by the tab, please see the code of the Tabs in my Container Component:

              <Tabs
                    className="DrawerTabs"
                    inkBarStyle={{ display: 'none' }}
                >
                    <Tab label="Headline"
                         data-route="/headline"
                         onActive={this.handleActive}
                         className={this.isActive('Headline')}
                    >
                        <div>
                            <ModulesListContainer
                                filter="Headline"
                            />

                        </div>
                    </Tab>
                    <Tab label="Body"
                         data-route="/body"
                         onActive={this.handleActive}
                         className={this.isActive('Body')}
                    >
                        <div>
                            <ModulesListContainer
                                filter="Body"
                            />
                        </div>
                    </Tab>
                    <Tab
                        label="Other"
                        data-route="/other"
                        onActive={this.handleActive}
                        className={this.isActive('Other')}
                    >
                        <div>
                            <ModulesListContainer
                                filter="Other"
                            />
                        </div>
                    </Tab>
                </Tabs>

and the code of the ModuleList I placed in each of the tabs which is showing only items based on the filter passed from the Container Component:

        const ModulesList = (props) => {

            let ListItems = props.modulesProps.map(module => {

                if (props.filter === module.category) {
                    return (
                        <ListItem
                            key={module.id}
                            className="ModulePreview"
                        >
                            {module.id} - {module.name} - {module.thumbnail}
                            <FontAwesome
                                name="plus-circle"
                                size="2x"
                                onClick={props.addModule.bind(this, module)}
                                className="AddModule"
                            />
                        </ListItem>
                    )
                }
            })

            return (
                <div className="ModulesList">
                    <List>
                        {ListItems}
                    </List>
                </div>
            )
        }

Even though I can see only the filtered items in each of the tabs (thus key is unique as each item is there only once) I'm still getting this warning:

Warning: flattenChildren(...): Encountered two children with the same key, 1 . Child keys must be unique; when two children share a key, only the first child will be used.

Why is that?

Any help / ideas / tips would be highly appreciated.

Thanks a lot in advance! :)

Meaning of that line is module.id is not unique, there will be 2 objects in array that have the same id=1 , to avoid that you can use index of object , it will always be unique.

Use this:

let ListItemsUI = [];
props.modulesProps.forEach((module, i) => {
    if (props.filter === module.category) {
        ListItemsUI.push (
            <ListItem
                key={i}
                className="ModulePreview"
            >
                {module.id} - {module.name} - {module.thumbnail}
                <FontAwesome
                    name="plus-circle"
                    size="2x"
                    onClick={props.addModule.bind(this, module)}
                    className="AddModule"
                />
            </ListItem>
        )
    }
})

return (
     <div className="ModulesList">
          <List>
              {ListItemsUI}
          </List>
     </div>
)

One more thing map is not suitable for these cases where you want to return only few element on the basis of condition, use forEach for that. Reason is if you don't return anything, by default map will return undefined .

Check the output of this example:

 let a = [1,2,3,4,5,6,7,8]; let b = a.map(el=>{ if(el % 2 == 0) return el; }) console.log(b); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM