Search code examples
javascriptreactjsreact-hookschakra-uiarray.prototype.map

I do not want all the "addToBasket" buttons to change when i click on a specefic "addToBasket" button. Only the clicked button should change


enter image description here

On clicking an "add to basket" button that specific button should get replaced by - and + buttons. Right now all of the mapped buttons are getting changed at the same time.

How to inflict change only on one "add to basket" button?

Using: React, Chakra UI buttons, and the .map function.

 {products.map((item) =>  {
            return (
             <Box key={item.id} border="1px solid black" h="auto" >
              
              <Link  to={`/product/single-product/${item.id}`}>
                
                <Box h="auto" border="1px solid black">
                <Box><Image src={item.image} h="fit-content" /></Box>
                <Text h="fit-content" >{item.name}</Text>
                <Text h="fit-content" >Rs.{item.price}</Text>
                </Box>

              </Link>

                <Box  align="center" border="1px solid black" h="50px" > 

                { addToBasket && <Button  onClick={() => handleAddToBasket(item)} ml="5px" >ADD TO BASKET</Button> }
                { addBtn && <Button ml="5px" onClick={handleReduceItem} >-</Button> }               
                { addBtn && <Button ml="5px" >+</Button> }

               </Box>
               
              </Box>
            
           )})}

button onClick functions are here:

const [addToBasket, setAddToBasket] = useState(true);
const [addBtn,setAddBtn] = useState(false);

 function handleAddToBasket(singleProduct){
   
    if(addToBasket === true){
      setAddToBasket(false)
      setAddBtn(true);
    }
    dispatch(addToCart(singleProduct))
  
  }

  function handleReduceItem(){
    if(addBtn === true){
      setAddToBasket(true)
      setAddBtn(false);
    }
  }

before clicking all button visible

after clicking all button are replaced by plus minus buttons


Solution

  • This solution only for add To Basket button. Note: You can utilize your Redux store state. I'm using local state only.

    First, You are using addToBasket state for all products and it's boolean value. So whenever you change the state of addToBasket is effects in all products.

    Change this Boolean to an array.

    const [basket, setAddToBasket] = useState([]);
    

    In handleAddToBasket make this changes.

    const [basket, setAddToBasket] = useState([]);
    const [addBtn,setAddBtn] = useState(false);
    
    function handleAddToBasket(singleProduct){
    
      if(!basket.includes(singleProduct.id)){
        setAddToBasket((ids) => [...ids, singleProduct.id])
        setAddBtn(true);
        dispatch(addToCart(singleProduct))
      } else {
        const newBasket = basket.filter((id) => id !== singleProduct.id)
        setAddToBasket(newBasket)
        // call your remove from cart dispatch here or however you want to handle it
      }
    }
    

    In jsx

    <Button  onClick={() => handleAddToBasket(item)} ml="5px" >{basket.includes(item.id) ? 'ADDED' : 'ADD TO BASKET' }</Button> 
    

    I think instead of just hiding the button you should display a text ADDED for already then you can toggle the item in your cart.