Reputation: 1168
I have a component where I want to show a ul
based upon an array of objects. These objects are Topics. I've created a Topics function which returns this ul
. In my component, I call the function like this:
<Topics topics={topics} />
The Topics
look like this:
0: {name: "Aanwezigen / afwezigen"}
1: {name: "Toevoegingen agenda"}
2: {name: "Update openstaande actiepunten"}
3:
children: Array(3)
0: {name: "Website"}
1: {name: "Social media"}
2: {name: "Nieuwsbrief"}
length: 3
__proto__: Array(0)
name: "Marketing"
__proto__: Object
4: {name: "Acquisitie", children: Array(3)}
5: {name: "Inkoop", children: Array(2)}
6: {name: "Jaarrekening 2018"}
7: {name: "Komende periode"}
8: {name: "Oplezen actiepunten"}
9: {name: "Rondvraag"}
This is my Topics function where I map through the topics and return an ul
.
function Topics({ topics }) {
return <ul>{topics.map(function (topic) { return <Topic topic={topic} /> })}</ul>;
}
This function calls the function Topic:
function Topic({ topic }) {
return (topic.hasOwnProperty('children')) ?
topic.children.forEach(child => {
<ul><li key={child.name}>{child.name}</li></ul>;
}) : <li key={topic.name}>{topic.name}</li>
}
In this function, I check if the object contains any children; and if it does, I loop through this array and create a new ul
with the li
elements in them. But, React gives me the below error:
Uncaught Invariant Violation: Topic(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
But, if I look at the ternary operator, it should always return something right? So, I don't understand where this error is coming from. To give you an idea on how it should look like:
Any help or ideas are appreciated. I just don't get why it says that it doesn't return anything while I think it does.
Upvotes: 0
Views: 76
Reputation: 2486
I hope you fetch recursive problem, you can apply Recursive function code here: https://codesandbox.io/s/elastic-fire-nxbt0
Recursive for your list like as:
const getHtmlStructure = items => {
let html = (
<ul>
{items.map(item => {
return (
<li>
{item.name}
{(item.children || []).length > 0
? getHtmlStructure(item.children)
: ""}
</li>
);
})}
</ul>
);
return html;
};
function App() {
let exampleData = [
{ id: 1, name: "name 1" },
{
id: 2,
name: "name 2",
children: [
{ id: 3, name: "name 2.1" },
{ id: 4, name: "name 2.2" },
{ id: 5, name: "name 2.3" }
]
},
{
id: 6,
name: "name 3",
children: [
{ id: 7, name: "name 3.1" },
{ id: 8, name: "name 3.2" },
{ id: 9, name: "name 3.3" }
]
},
{ id: 10, name: "name 4" },
{ id: 11, name: "name 5" }
];
return (
<div className="App">
<h1>Item List</h1>
<Items data={exampleData} />
</div>
);
}
import React from "react";
export default function Items(props) {
const getHtmlStructure = items => {
let html = (
<ul>
{items.map(item => {
return (
<li>
{item.name}
{(item.children || []).length > 0
? getHtmlStructure(item.children)
: ""}
</li>
);
})}
</ul>
);
return html;
};
const { data } = props;
return (data || []).length > 0 ? getHtmlStructure(data) : "No items";
}
Thank you
Upvotes: 1
Reputation: 10307
Do not use forEach
if you intend to loop through an array to render something.
The forEach method returns undefined.
The forEach() method executes a provided function once for each array element.
Use map instead.
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
It should be:
<>
...
{yourArray.map(item => <YourComponent key={item.id} />)}
...
</>
Upvotes: 0