Map to list products in React with dropdown, how to open specific dropdown of each product?

Asked

Viewed 115 times

2

I’m using the map to make a list of products, until then quiet, but in the layout there is a dropdown where we will present more information of that item, until then quiet also.

But my problem is that when I open the dropdown of a specific product, it opens the dropdown of all products. I would like to know how to pass a parameter to identify and open only the dropdown of the specific product.

Follow the JSX code snippet:

{this.state.products.map(product => (
   <tr className="list-item-row-payment" key={product.id}>
         <td>{product.id}</td> 
         <td>{product.name}</td>       
         <td>
            <div className="itens-acoes">
                <button onClick={() => this.showDropdownDoc()}>More</button>
                <div className={this.state.DropdownDoc}>
                    <td>{product.origin}</td>
                    <td>{product.link}</td> 
                </div>
            </div>
         </td>
    </tr>
  ))}

NOTE: I am using CSS with None display to hide through the state.

Function of the dropdown:

showDropdownDoc = () => {
    if (this.state.DropdownDoc === "true") {
        this.setState({ DropdownDoc: "hide" });
        console.log(this.state)
    } else {
        this.setState({ DropdownDoc: "true" });
    }
}

My state:

this.state = {  
   DropdownDoc: "hide",
}
  • Convert the code snippet where you render your trs into a New React component. This way you can maintain the state of the dropdown in each child component. <Componentefilho product={product} />

1 answer

2


The solution I would use in that case would be a ternary which would cause the following changes in the code: Would receive the index in the map:

this.state.products.map((product,index) => (

Pass this index to showDropdownDoc function:

<button onClick={() => this.showDropdownDoc(index)}>More</button>

It would receive inside the function and save this index in the state:

   showDropdownDoc = (indexPassado) => {
        if (this.state.DropdownDoc === "true") {
            this.setState({ DropdownDoc: "hide", index: indexPassado });

Would set the index property to state:

this.state = {  
   DropdownDoc: "hide",
   index: '',
}

And where you pass the validate classname if it is in the correct index when it was clicked:

               <div className={(index===this.state.index)?this.state.DropdownDoc:true}>
                    <td>{product.origin}</td>
                    <td>{product.link}</td> 
                </div>

There are other ways to do the same by making it simpler, but with the logica already built this was the solution I could find.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.