Reputation: 147
I am currently trying to make a HTML table work in React, but something isn't going the way it should. I do get a render output but with the error of: <tr> cannot appear as a child of <div>
.
I tried to find it online, but the technique I am using doesn't seem to be used that often, so if I am doing that wrong, please enlighten me.
Thank you in advance!
getTableContent = (arr) => {
let result = [];
arr.forEach(function (item, i) {
result.push(
<table key={item.productType}>
<thead>{item.productType}</thead>
<tbody>
{item.contents.forEach(function (nextItem, j) {
result.push(
<tr key={nextItem.type}>
<td>{nextItem.type}</td>
<td>{nextItem.count}</td>
</tr>
)
})}
</tbody>
</table>
);
});
return result;
};
render() {
return (
<div>{this.getTableContent(productSpecification)}</div>
);
}
The data looks as follows:
const productSpecification = [
{
productType: "abc", contents: [
{type: "abc", count: 231},
{type: "abc", count: 56},
{type: "abc", count: 54},
{type: "abc", count: 544},
{type: "abc", count: 54},
{type: "abc", count: 564},
{type: "abc", count: 4},
{type: "abc", count: 4564},
{type: "abc", count: 4531},
{type: "abc", count: 234},
{type: "abc", count: 57},
{type: "abc", count: 7}
]
}
];
Upvotes: 5
Views: 26219
Reputation: 4387
This is supposed to return tr
rows:
{item.contents.forEach(function (nextItem, j) {
result.push(
<tr key={nextItem.type}>
<td>{nextItem.type}</td>
<td>{nextItem.count}</td>
</tr>
)
})}
But in fact it modifies the result
variable, pushing the tr
s to it instead of returning them. This causes the result
variable to be full of both table
s and tr
s. You should return the tr
s in map
, not push them to result
in a forEach
:
{item.contents.map(function (nextItem, j) {
return (
<tr key={nextItem.type}>
<td>{nextItem.type}</td>
<td>{nextItem.count}</td>
</tr>
)
})}
Upvotes: 0
Reputation: 957
instead of pushing to array
you can try return jsx
from function
Try this.
getTableContent = (arr) => {
const iterateItem = (item) => {
return item.map(function (nextItem, j) {
return (
<tr key={nextItem.type}>
<td>{nextItem.type}</td>
<td>{nextItem.count}</td>
</tr>
);
})
}
return arr.map(function (item, i) {
return (
<table key={item.productType}>
<thead>{item.productType}</thead>
<tbody>
{iterateItem(item.contents)}
</tbody>
</table>
);
});
};
render() {
return (
<div>{this.getTableContent(productSpecification)}</div>
);
}
Upvotes: 6
Reputation: 1
You need to add opening and closing <tbody>
tags, like this:
<table>
<tbody>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
...
</tbody>
</table>
Upvotes: 0