mmalak
mmalak

Reputation: 127

How to pass react hook state to another component for each click

I stuck in this moment creating store with different products, that I want to add to the basket. The problem occur when I wanted to pass the state of cardList into Basket component to change the information from "Basket is empty" to display information how many items are currently in basket.

Below I paste my main hooks component with basket component which include all functionality.

Basket component:

import React from 'react'

const Basket = (props) => {

return (
    <div>
        {props.cardItems.length === 0 ? "Basket is empty" : <div> You have {props.cardItems.length} products in basket!</div>}
    </div>
)

}

export default Basket;

Main component:

    function 
  const [cardItems, setCardItems] = useState([]);
  const price = 2.50;

  useEffect(() => {
    fetch(URL, {
      method: 'GET',
      headers: {
        Accept: "application/json",
      }
    }).then(res => res.json())
      .then(json => (setBeers(json), setFilteredBeers(json))
      );
  }, [])


  function handleMatches(toMatch) {...
  }

  const displayFilterBeers = event => {...
  }

  const handleRemoveCard = () => {...

  }

  const handleAddToBasket = (event, beer) => {
    setCardItems(state => {
      let beerAlreadyInBasket = false;
      cardItems.forEach(item => {
        if (item.id === beer.id) {
          beerAlreadyInBasket = true;
          item.count++;
        };
      });
      if (!beerAlreadyInBasket) {
        cardItems.push({ ...beer, count: 1 })
      }
      localStorage.setItem('baketItems', JSON.stringify(cardItems));
      console.log('cardItems: ', cardItems, cardItems.length);
      return cardItems;
    })
  }

  return (
    <div className="App">
      <div className='search'>
        <input type='text' placeholder='search beer...' onChange={displayFilterBeers} />
      </div>
      <BeerList BeersList={filteredBeers} price={price} handleAddToBasket={handleAddToBasket} />
      <Basket cardItems={cardItems}/>
    </div>
  );
}

export default App;

I saw an example that without React hooks that in basket component someone used const {cartItems} = this.props; but I don't know how to achieve something similar using hooks.

Upvotes: 2

Views: 8686

Answers (1)

Arnab Roy
Arnab Roy

Reputation: 619

I think what you are facing is related to this issue.

So when dealing with array or list as state, react doesn't re-render if you don't set state value to a new instance. It assumes from the high-level comparison that the state hasn't been changed. So it bails out from the re-rendering.

from the issue I found this solution is better than the others -

const handleAddToBasket = (event, beer) => {
  const nextState = [...cardItems, beer] // this will create a new array, thus will ensure a re-render
  // do other stuffs
  setCardItems(nextState);
 };

Upvotes: 4

Related Questions