I'm writing custom nested recursive accordion component to display objects, In that component I'm getting an error each child in a list should have a unique key prop, not sure where I need to put the key property
how to resolve the same.
accordion.js:
import React, { useState, useCallback } from 'react'
import { Container, Grid } from '@material-ui/core'
import './styles.css'
function Accodian({ explorer }) {
const [ expand, setExpand ] = useState(false)
const handleExpand = useCallback(() => {
setExpand(prevState => !prevState)
})
if (explorer.children) {
return (
<div style={{ width: '100%' }} className={'tabs'} key={explorer.label}>
{explorer.children ? (
<>
<div className='tab' onClick={handleExpand}>
<label className={ expand ? 'tab-label-expanded' : 'tab-label' }>
{explorer.label}
</label>
</div>
{expand ? (
<Container className='tab-content'>
<Grid container spacing={1}>
{explorer.children.map(child => {
return (
<React.Fragment>
{Array.isArray(child.children) ? (
<Accodian explorer={child}/>
) : (
<Grid item xs={12} sm={6} md={6} lg={4} xl={3}>
<li>
<b>{child.label}</b>{' '}: {child.value}
</li>
</Grid>
)}
</React.Fragment>
)
})}
</Grid>
</Container>
) : null}
</>
) : null}
</div>
)
} else {
return <div style={{ paddingLeft: '20px' }}>{explorer.label}</div>
}
}
export default Accodian
After did many analysis found the place where we can able to apply the key in the component
Solution: <React.Fragment key={child.label}>
import React, { useState, useCallback } from 'react'
import { Container, Grid } from '@material-ui/core'
import './styles.css'
function Accodian({ explorer }) {
const [ expand, setExpand ] = useState(false)
const handleExpand = useCallback(() => {
setExpand(prevState => !prevState)
})
if (explorer.children) {
return (
<div style={{ width: '100%' }} className={'tabs'} key={explorer.label}>
{explorer.children ? (
<>
<div className='tab' onClick={handleExpand}>
<label className={ expand ? 'tab-label-expanded' : 'tab-label' }>
{explorer.label}
</label>
</div>
{expand ? (
<Container className='tab-content'>
<Grid container spacing={1}>
{explorer.children.map(child => {
return (
<React.Fragment key={child.label}> // applied key
{Array.isArray(child.children) ? (
<Accodian explorer={child}/>
) : (
<Grid item xs={12} sm={6} md={6} lg={4} xl={3}>
<li>
<b>{child.label}</b>{' '}: {child.value}
</li>
</Grid>
)}
</React.Fragment>
)
})}
</Grid>
</Container>
) : null}
</>
) : null}
</div>
)
} else {
return <div style={{ paddingLeft: '20px' }}>{explorer.label}</div>
}
}
export default Accodian