-1

Necessary imports eg useState, useDispatch

function ItemCard(props) {
  const [count, setCount] = useState(0);
  const dispatch = useDispatch();

Here I am trying to use a button which triggers this function and increases count, but when I console.log it, it prints the older value. When I send the count to dispatch, the older value also gets passed in.

  const addCount = () => {
    setCount((prevCount) => prevCount + 1);
    console.log(count);
    dispatch(
      updateCart(
        "ADD_TO_CART",
        { id: props.id, name: props.name, price: props.price },
        count
      )
    );
  };

  const decreaseCount = () => {
    if (count > 0) {
      setCount((prevCount) => prevCount - 1);
      dispatch(
        updateCart(
          "REMOVE_FROM_CART",
          { id: props.id, name: props.name, price: props.price },
          count
        )
      );
    }
  };

  return (
    <div className="card">
      <div className="image">
        <img src={props.img} alt="cookie" />
      </div>

      <div className="title">
        <h2>{props.name}</h2>
        <h2>Rs.{props.price}</h2>
      </div>

      <p className="detail">{props.detail}</p>

      <div className="buttons">
        <button onClick={addCount} id="add-to-cart">
          +
        </button>
        <span>{count}</span>
        <button onClick={decreaseCount} id="add-to-cart">
          -
        </button>
      </div>
    </div>
  );
}

export default ItemCard;


Ali
  • 2,702
  • 3
  • 32
  • 54
Usama Nadeem
  • 75
  • 3
  • 10
  • Of course the value is still the older one, you don't reassign count until *next* time the component is rendered. – jonrsharpe Jun 25 '20 at 22:54
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – jonrsharpe Jun 25 '20 at 22:54
  • There are 2 major problems with this code; 1. magic strings REMOVE_FROM_CART and ADD_TO_CART, better make the function removeFromCart and define these strings as constants to be imported by the action creators and the reducers/middleware. 2. You are copying count value in local state and save it in redux state, there is no need for this duplication as the component can get count from redux state. – HMR Jun 26 '20 at 08:22

2 Answers2

0

You should update your state in this way :

 SetCount (count + 1)

And attention please to this fact that your state is updated after the addCount function run

S. Hesam
  • 5,266
  • 3
  • 37
  • 59
0

setState is async, so you would have to use a local variable or use useEffect to watch when the state is already updated

  const decreaseCount = () => {
    if (count > 0) {
      setCount((prevCount) => prevCount - 1);
    }
  };

  useEffect(() => {
    dispatch(
        updateCart(
          "REMOVE_FROM_CART",
          { id: props.id, name: props.name, price: props.price },
          count
        )
      );
  }, [count])

or

  const decreaseCount = () => {
    if (count > 0) {
      const localCount = count - 1;
      dispatch(
        updateCart(
          "REMOVE_FROM_CART",
          { id: props.id, name: props.name, price: props.price },
          localCount
        )
      );
      setCount((prevCount) => prevCount - 1);
    }
  };
ludwiguer
  • 2,177
  • 2
  • 15
  • 21
  • The technique on bottom solves the problem, but how comes that the technique you described on top also solves it? As I have two different dispatches that are to be called based on which button is pressed. The useEffect that you wrote just solves for one of them. Can you elaborate on that? – Usama Nadeem Jun 26 '20 at 00:02