Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix validateDOMNesting(...): <td> cannot appear as a child of <tbody>. and Each child in a list should have a unique "key" prop

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

like image 245
HardRock Avatar asked Apr 29 '20 09:04

HardRock


1 Answers

For: 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?

like image 198
developer Avatar answered Sep 28 '22 18:09

developer