React button elements function called for every button

There is a object called productData in which data is fetched from database and through map function i have created various Card element to show different products, which is done in variable called productsElement and there button which conatins a function to delete that product from database and that function requires a product id so it can delete that particular product but whenever i click that button every buttons function is clicked.
So tell me how can I stop that so only a particular button function is called and that can delete the that particular product and not that all .

import React from 'react'
import ShippingFree from '../freeShipping.png'
import Featured from '../featured.png'
import Axios from 'axios'
import { Card, Button } from 'react-bootstrap'

export default function ProductCard({ productData }) {
  const productUrl = 'http://localhost:4000/api/v1/products/'

  const deleteProduct = async (productId) => {
    console.log('inside')
    await Axios.delete(productUrl + productId, {})
      .then((res) => {
        console.log(res)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const productsElement = productData.map((item) => {
    return (
      <Card className='card-group' key={item._id}>
        <Button variant='danger' onCLick={deleteProduct(item._id)}>
          Danger
        </Button>
        <Card.Img variant='top' src={item.image} className='card-img' />
        <Card.Body>
          <Card.Title>{item.name}</Card.Title>
          <Card.Title>Brand: {item.company}</Card.Title>
          <Card.Text>{`NPR ${item.price}`}</Card.Text>
          <Card.Text>{item.description}</Card.Text>
          {item.freeShipping && (
            <img
              src={ShippingFree}
              alt='shippingfree'
              className='shippingFree-img'
            />
          )}
          {item.featured && (
            <img
              src={Featured}
              alt='shippingfree'
              className='shippingFree-img'
            />
          )}
        </Card.Body>
      </Card>
    )
  })
  return <>{productsElement}</>
}

This catches my eye. You need to pass onClick a function.

This is a function: deleteProduct

This is not a function: _deleteProduct(item.id)

That is a function that is being called and the return value is being passed to onClick. That is a big difference. That function will be run as soon as the component is rendered, it will not wait until the button is clicked.

It gets tricky if you need to pass a parameter like that. One of the simplest ways to handle it is to wrap it in an arrow function:

onCLick={() => deleteProduct(item._id)}

Now, onClick gets a function, an anonymous arrow function that will be called when the click is done.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.