I have a tabs component that accepts the elements array as props and I am trying to assign key to cloned elements by using React.cloneElement() with no luck. I am passing down elements as an array. Mapping over that elements array, cloning each component in that array and trying to assign key to each element.But, I still keep getting the warning about each component should have a key prop. How can I assign keys to each component by using React.cloneElement()?
Below is my elements array that I am passing to my Tabs component.
Below is my tabs component:
import React, {useState, useEffect, useCallback} from 'react';
import classes from './tabs.module.css';
const Tabs = ({ tabsData, active = 0 }) => {
const [activeTab, setActiveTab] = useState(active);
const setActiveTabIndex = useCallback((index) => {
setActiveTab(index)
}, [activeTab])
return (
<div className={classes.tabsContainer}>
<ul className={classes.tabsList}>
{
tabsData.map((item, index) => (
<li className={`${classes.tab} ${index === activeTab && classes.activeTab}`} onClick={() => setActiveTabIndex(index)}>{ item.tabTitle }</li>
))}
</ul>
<div className={classes.textContainer}>
{tabsData[activeTab].content.map((ElementItem, index) => (
React.cloneElement(ElementItem, {key:index})
))}
</div>
</div>
)
}
export default Tabs
Below is the array that I am passing down to that tabs component.
const tabsData = [
{
tabTitle: "Description",
content: [<h1 className={classes.tabTitle}>{'Product Description'}</h1>, productDetails.shortDescription.html ? <RichContent html={productDetails.shortDescription.html} /> : <RichContent html={"<p>No short description found</p>"} />]
},
{
tabTitle: "Attributes",
content: [<h1 className={classes.tabTitle}>{'Product Attributes'}</h1>, <CustomAttributes customAttributes={customAttributesDetails.list} />]
}
]
I have also tried the following to try to assign key to each element.
<React.Fragment key={index}>
{ React.cloneElement(ElementItem) }
</React.Fragment>
CodePudding user response:
Problem is in this part of the code
<ul className={classes.tabsList}>
{tabsData.map((item, index) => (
<li key={index} className={`${classes.tab} ${index === activeTab &&
classes.activeTab}`} onClick={() => setActiveTabIndex(index)}>{ item.tabTitle }</li>
))}
</ul>
You should also add key
prop to each li
element