Reputation: 3075
I am attempting to build out some tabbed content based on this tutorial. When I set up my app exactly like the tutorial, everything works great. The problem is I want to build these tabs with dynamic content, and sometimes there will not be any content for one or more of the tabs, so I am attempting to generate the tabs based on the data coming in.
Here is what I have attempted:
let tab1 = "Tab 1";
let tab2 = "Tab 2";
let tab3 = false;
let tab4 = "Tab 4";
class Gallery extends Component {
render() {
let tabs;
if (tab1) {
tabs += (
<div label="Gator">
See ya later, <em>Alligator</em>!
</div>
);
}
if (tab2) {
tabs += (
<div label="Croc">
After 'while, <em>Crocodile</em>!
</div>
);
}
if (tab3) {
tabs += (
<div label="Sarcosuchus">
Nothing to see here, this tab is <em>extinct</em>!
</div>
);
}
if (tab4) {
tabs += (
<div label="Gator">
See ya later, <em>Alligator</em>!
</div>
);
}
return (
// THIS WORKS
<Tabs>
<div label="Gator">
See ya later, <em>Alligator</em>!
</div>
<div label="Croc">
After 'while, <em>Crocodile</em>!
</div>
<div label="Sarcosuchus">
Nothing to see here, this tab is <em>extinct</em>!
</div>
</Tabs>
// THIS DOESN'T
// <Tabs>
// {tabs}
// </Tabs>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Gallery />, rootElement);
If you comment out the hardcoded child divs within the Tabs component and uncomment the one where I am using the tabs
variable, you can see that there is an error. The error is TypeError: Cannot read property 'label' of undefined
on line 15
of Tabs/index.js
so it would appear that the children aren't being rendered before the activeTab
state is being set. Maybe I am going about this all wrong anyway. Is there a better way to dynamically populate these tabs?
Note that in my actual implementation, the tab1/2/3 is actually JSON, I just hardcoded them as variables for this question.
Upvotes: 1
Views: 1543
Reputation: 5189
You are expecting your children to be an "array" therefore just concatenating JSX won't do.
You need to create an array with those JSX elements and pass in as children
class Gallery extends Component {
render() {
let tabs = [];
if (tab1) {
tabs.push(
<div label="Gator">
See ya later, <em>Alligator</em>!
</div>
);
}
if (tab2) {
tabs.push(
<div label="Croc">
After 'while, <em>Crocodile</em>!
</div>
);
}
if (tab3) {
tabs.push(
<div label="Sarcosuchus">
Nothing to see here, this tab is <em>extinct</em>!
</div>
);
}
if (tab4) {
tabs.push(
<div label="Gator">
See ya later, <em>Alligator</em>!
</div>
);
}
return (
// THIS WORKS
// <Tabs>
// <div label="Gator">
// See ya later, <em>Alligator</em>!
// </div>
// <div label="Croc">
// After 'while, <em>Crocodile</em>!
// </div>
// <div label="Sarcosuchus">
// Nothing to see here, this tab is <em>extinct</em>!
// </div>
// </Tabs>
// THIS DOESN'T
<Tabs>{tabs}</Tabs>
);
}
}
Working sandbox --> https://codesandbox.io/s/amazing-sky-hezzy
Upvotes: 1