渲染次数过多。React限制了渲染的次数以防止无限循环。在渲染方法中更新函数式组件的状态。

3
每当我显示购物车项目时,我想使用render方法内的useState函数更新总价格和商品数量。但是,在UI呈现后立即出现了上述React错误。 有没有更好的方法可以实现我的目标而不会出错?
const Cart = () => {
  const cartItems = useItems()
  const firebase = useFirebase()
  //Items count

  //Total amount of the items
  let [total, updateTotal] = useState(0)
  let [count, updateCount] = useState(1)

  //Method to add items to the cart
  useEffect(() => {
    if (!firebase) return
  }, [firebase, cartItems])




  return (
    <Layout>
      <SEO title="Cart" />
      <Navbar count={count} />
      <MDBContainer>
        <MDBCol lg="12" className="">
          <MDBTable responsive className="mt-5 z-depth-1">
            <MDBTableHead>
              <tr className="bg-light">
                <th>
                  <div className="p-1 px-3 text-uppercase font-weight-bold">
                    Product
                  </div>
                </th>
                <th>
                  <div className="p-1 px-3 text-uppercase font-weight-bold">
                    Price
                  </div>
                </th>
                <th>
                  <div className="p-1 px-3 text-uppercase font-weight-bold">
                    Quantity
                  </div>
                </th>
                <th>
                  <div className="p-1 px-3 text-uppercase font-weight-bold">
                    Remove
                  </div>
                </th>
              </tr>
            </MDBTableHead>
            <MDBTableBody id="products-list">
              {cartItems.map(product => {
                updateTotal((total += product.price))
                updateCount((count += 1))
                return (
                  <tr>
                    <td class="px-3 font-weight-normal">
                      {product.name} <span class="d-none">{product.id}</span>{" "}
                    </td>
                    <td width="10%" class="text-center font-weight-normal">
                      {product.price}
                      <span>/kg </span>{" "}
                    </td>
                    <td width="10%" class="text-center font-weight-normal">
                      {product.count}
                    </td>
                    <td width="10%" class="text-center">
                      <div class="px-3 font-weight-normal">
                        {" "}
                        <button
                          class="bg-transparent border-0"
                          id="delete-button"
                        >
                          <i class="fa fa-trash-alt delete-icon"></i>
                        </button>
                      </div>
                    </td>
                  </tr>
                )
              })}
            </MDBTableBody>
            <MDBTableFoot>
              <tr>
                <td className="px-3 text-uppercase font-weight-bold">Total</td>
                <td className="font-weight-bold px-5">&#8377;{total}</td>
                <td className="font-weight-bold pr-2 text-center">{count}</td>
              </tr>
            </MDBTableFoot>
          </MDBTable>
        </MDBCol>
      </MDBContainer>
    </Layout>
  )
}

export default Cart

亲爱的@KaranSiddannavar,如果可能的话,请编辑您的帖子标题。短标题更易于其他用户阅读。我认为这样更好。也许您可以将问题的一些概念迁移到帖子内部,而不是标题。非常感谢,伙计。祝你度过愉快的时光。 - AmerllicA
useEffect(() => { if (!firebase) return }, [firebase, cartItems])每次 firebase 或 cartItems 发生变化时,都会调用这个 hooks。将 [firebase, cartItems] 改为 []。 - Pratap Sharma
我只是检查Firebase实例是否已初始化。 - Karan Siddannavar
你可以加入这个聊天室并讨论问题:https://chat.stackoverflow.com/rooms/206191/discuss。 - simbathesailor
我已经在那里给你发了消息,请回复! - Karan Siddannavar
显示剩余7条评论
3个回答

3

请使用空白的[]代替[firebase,cartItems]


我做到了!但是,在return方法中使用state时,我仍然遇到了相同的错误。 - Karan Siddannavar

3
以下代码应该适用于您:
const cartItems = useItems();
// I assume this gives you cartItems.

let [total, updateTotal] = useState(() => {
  if (cartItems) {
    // item object {id: "2", name: "Cucumber", category: "vegetable", price: 50, // //count: 0}
    return cartItems.reduce((acc, elem) => {
      acc += elem.price * elem.count;
      return acc;
    }, 0);
  }
  return 0;
});
let [count, updateCount] = useState(cartItems.length);

React.useEffect(() => {
  if (cartItems) {
    updateCount(cartItems.length);
    // item object {id: "2", name: "Cucumber", category: "vegetable", price: 50, // //count: 0}
    const total = cartItems.reduce((acc, elem) => {
      acc += elem.price * elem.count;
      return acc;
    }, 0);
    updateTotal(total);
  }
}, [cartItems]);

所以,基本上当你从 useItems 获取到某个值后,需要初始化该状态,并且在 cartItems 引用更改时也需要更新它。

你能在我们的聊天中回复吗?我需要一些帮助。 - Karan Siddannavar

0

将 [firebase,cartItems] 放入代码中会告诉 React 如果这两个参数发生任何更改,就始终重新渲染。这就是为什么会出现过多的重新渲染。


我从来没有因为这样做而出现错误!我在return方法中使用useState()时出现了错误。 - Karan Siddannavar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接