I am trying to fix these two warnings:
Warning: validateDOMNesting(...): <td> cannot appear as a child of <tbody>.
Warning: Each child in a list should have a unique "key" prop.
Here is my table js file:
<table className="table table-hover">
<thead>
<tr>
<th scope="col"style={{width: "10%"}}>ID</th>
<th scope="col"style={{width: "10%"}}>Name</th>
<th scope="col"style={{width: "10%"}}>Price $</th>
<th scope="col" style={{width: "10%"}}>Quantity</th>
<th scope="col" style={{width: "10%"}}>Total $:</th>
<th scope="col" style={{width: "10%"}}>Total €:</th>
<th scope="col" style={{width: "20%"}}>Remove:</th>
<th scope="col" style={{width: "20%"}}>Change Quantity:</th>
</tr>
</thead>
{this.state.products.map(data=>
<tbody>
<td>{data.id}</td>
<td>{data.name}</td>
<td>{data.price}</td>
<td>{data.quantity}</td>
<td>{data.quantity*data.price}</td>
<td>{Math.round(data.quantity*data.price*0.92)}</td>
<td>
<button type="button" onClick={(e)=>this.handleSubmitRemove(data.id)} className="btn btn-danger">Remove</button>
</td>
<td>
<button style={{margin: "3px"}} type="button" onClick={(e)=> this.updateCart(data.id,1)}>+</button>
<button style={{margin: "3px"}} disabled={data.quantity==1} type="button" onClick={(e)=> this.updateCart(data.id,-1)}>-</button>
</td>
</tbody>
)}
</table>
I tried to get <tbody>
outside the this.state.products.map(data=>
but then I have another error
JSX expressions must have one parent element.
Any help or idea would be appreciated to solve this issue.
Thank you so much! Have a nice day
I am trying to fix these two warnings:
Warning: validateDOMNesting(...): <td> cannot appear as a child of <tbody>.
Warning: Each child in a list should have a unique "key" prop.
Here is my table js file:
<table className="table table-hover">
<thead>
<tr>
<th scope="col"style={{width: "10%"}}>ID</th>
<th scope="col"style={{width: "10%"}}>Name</th>
<th scope="col"style={{width: "10%"}}>Price $</th>
<th scope="col" style={{width: "10%"}}>Quantity</th>
<th scope="col" style={{width: "10%"}}>Total $:</th>
<th scope="col" style={{width: "10%"}}>Total €:</th>
<th scope="col" style={{width: "20%"}}>Remove:</th>
<th scope="col" style={{width: "20%"}}>Change Quantity:</th>
</tr>
</thead>
{this.state.products.map(data=>
<tbody>
<td>{data.id}</td>
<td>{data.name}</td>
<td>{data.price}</td>
<td>{data.quantity}</td>
<td>{data.quantity*data.price}</td>
<td>{Math.round(data.quantity*data.price*0.92)}</td>
<td>
<button type="button" onClick={(e)=>this.handleSubmitRemove(data.id)} className="btn btn-danger">Remove</button>
</td>
<td>
<button style={{margin: "3px"}} type="button" onClick={(e)=> this.updateCart(data.id,1)}>+</button>
<button style={{margin: "3px"}} disabled={data.quantity==1} type="button" onClick={(e)=> this.updateCart(data.id,-1)}>-</button>
</td>
</tbody>
)}
</table>
I tried to get <tbody>
outside the this.state.products.map(data=>
but then I have another error
JSX expressions must have one parent element.
Any help or idea would be appreciated to solve this issue.
Thank you so much! Have a nice day
Share Improve this question asked Apr 29, 2020 at 9:26 HardRockHardRock 1,0912 gold badges17 silver badges42 bronze badges 4 |2 Answers
Reset to default 14For: Warning: validateDOMNesting(...): <td> cannot appear as a child of <tbody>.
- Simply add a row to your <tbody>
i.e.
<tbody><tr><td></td></tr></tbody>
The correct html structure of a table is shown here:
ref: https://www.w3schools.com/tags/tag_tbody.asp
and for: Warning: Each child in a list should have a unique "key" prop.
Change you map from : this.state.products.map(data=>
to: this.state.products.map((data, myKey)=>
then use this key in your <tbody>
like this: <tbody key={myKey}>
React components require a unique key. when using map to generate child components in earlier versions, implementors had to set this. The simplest way to do this is to use the item index from the map function, in the root element of your child.
ref: https://reactjs.org/docs/lists-and-keys.html
<table className="table table-hover">
<thead>
<tr>
<th scope="col"style={{width: "10%"}}>ID</th>
<th scope="col"style={{width: "10%"}}>Name</th>
<th scope="col"style={{width: "10%"}}>Price $</th>
<th scope="col" style={{width: "10%"}}>Quantity</th>
<th scope="col" style={{width: "10%"}}>Total $:</th>
<th scope="col" style={{width: "10%"}}>Total €:</th>
<th scope="col" style={{width: "20%"}}>Remove:</th>
<th scope="col" style={{width: "20%"}}>Change Quantity:</th>
</tr>
</thead>
{this.state.products.map((data, myKey) =>
<tbody key={myKey}>
<tr>
<td>{data.id}</td>
<td>{data.name}</td>
<td>{data.price}</td>
<td>{data.quantity}</td>
<td>{data.quantity*data.price}</td>
<td>{Math.round(data.quantity*data.price*0.92)}</td>
<td>
<button type="button" onClick={(e)=>this.handleSubmitRemove(data.id)} className="btn btn-danger">Remove</button>
</td>
<td>
<button style={{margin: "3px"}} type="button" onClick={(e)=> this.updateCart(data.id,1)}>+</button>
<button style={{margin: "3px"}} disabled={data.quantity==1} type="button" onClick={(e)=> this.updateCart(data.id,-1)}>-</button>
</td>
</tr>
</tbody>
)}
</table>
For more information about this: JSX expressions must have one parent element.
See this post:
React - expressions must have one parent element?
I faced an error which said this:
How to fix validateDOMNesting(…): <th> cannot appear as a child of <thead>. and Each child in a list should have a unique “key” prop
.
I finally found out that I was missing <tr></tr>
after <thead></thead>
tag. So check in your <thead></thead>
tag and see whether your other <th></th>
tags are enclosed within <tr></tr>
tag. Finally your code should look like this:
<thead>
<tr>
<th>
//other content here like <td>
</th>
</tr>
</thead>
Warning: validateDOMNesting(...): <td> cannot appear as a child of <tbody>.
- Simply add a row to your<tbody>
i.e.<tbody><tr><td></td></tr></tbody>
– developer Commented Apr 29, 2020 at 9:29Warning: Each child in a list should have a unique "key" prop.
change you map from :this.state.products.map(data=>
to this.state.products.map((data, myKey)=>` then use this key in your<tbody>
like this:<tbody key={myKey}>
– developer Commented Apr 29, 2020 at 9:31