useEffect 看不到状态更新

useEffect does not see the state update

我正在尝试通过更新产品数量和总金额的计数器来实现将产品添加到购物车的功能。

我不明白为什么useEffect只有在新产品加入购物车时才会触发。如果我更新购物车中已有产品的当前数量,则 useEffect 不起作用。

  const [cart, setCart] = useState([])
  const [counter, setCounter] = useState(cart.reduce((prev, curr) => prev + curr.quantity, 0))
  const [total, setTotal] = useState(cart.reduce((prev, curr) => prev + curr.price, 0))

  const addItemToCart = (id, foodName, url, price, quantity) => {
    if (cart.find(el => el.id === id)) {
      cart.map(el => {
        if (id === el.id) {
          const price = el.price / el.quantity
          el.quantity += 1
          el.price = price * el.quantity
        }
        return setCart(cart) // useEffect does not work
      })
    } else {
      setCart(() => [...cart, { id, foodName, url, price, quantity }]) // useEffect is triggered
    }
  }

  useEffect(() => {
    setCounter(cart.reduce((prev, curr) => prev + curr.quantity, 0))
    setTotal(cart.reduce((prev, curr) => prev + curr.price, 0))
  }, [cart])

而不是这个

 return setCart(cart) // useEffect does not work

写入

      setCart(prevCart => prevCart.map(el => {
        if (id === el.id) {
          const price = el.price / el.quantity
          el.quantity += 1
          el.price = price * el.quantity
        }
        return el
      }))

您的代码有两个问题:

  cart.map(el => {
    if (id === el.id) {
      const price = el.price / el.quantity
      el.quantity += 1
      el.price = price * el.quantity
    }

这没有 return 任何东西。 Cart.map 不会改变列表。所以购物车会是一样的我猜对象会发生变化,所以 setCart([...cart]) 之后会起作用。

return setCart(cart) // useEffect does not work

setCart只能拿一份cart。这也不会做任何事情(参见:https://reactjs.org/docs/hooks-state.html

完全更新代码

  const addItemToCart = (id, foodName, url, price, quantity) => {
    if (cart.find(el => el.id === id)) {
      setCart(prevCart => prevCart.map(el => {
        if (id === el.id) {
          const price = el.price / el.quantity
          el.quantity += 1
          el.price = price * el.quantity
        }
        return el
      }))

    } else {
      setCart(() => [...cart, { id, foodName, url, price, quantity }]) // useEffect is triggered
    }
  }