如何在React中从子组件的循环中累加数值?

huangapple go评论74阅读模式
英文:

How can I sum up a value from a loop of child components in react?

问题

我有两个React组件,一个是Cart,另一个是CartItem,在Cart中,我使用.map循环CartItem。在CartItem中,我有一个名为total的行,它等于price * item.count。我要如何计算所有行的总和,而不管有多少个CartItem,然后返回总计,以便我可以得到购物车的总值。

我尝试添加一个handleTotal函数,但它只返回一个元素的行总和,而不是所有元素的总和。

以下是CartItem组件:

const CartItem = ({ item, handleTotal }) => {
  var [itemCount, setItemCount] = useState(1);
  var [lineTotal, setLineTotal] = useState(item.price);

  const incrementCount = () => {
    setItemCount(++itemCount);
  };
  const decrementCount = () => {
    setItemCount(--itemCount);
  };

  useEffect(() => {
    handleTotal(item.id, lineTotal);
  }, []);

  return (
    <div>
      <Product>
        <ProductDetail>
          <Image src={item.image} />
          <Details>
            <ProductName>
              <b>产品</b> {item.name}
            </ProductName>
            <ProductId>
              <b>ID</b> {item.id}
            </ProductId>
            <ProductColor color={item.color} />
            <ProductSize>
              <b>尺码</b> {item.size}
            </ProductSize>
          </Details>
        </ProductDetail>
        <PriceDetail>
          <ProductAmountContainer>
            <Add onClick={() => { incrementCount(); setLineTotal(item.price * itemCount) }} />
            <ProductAmount>{itemCount}</ProductAmount>
            <Remove onClick={() => { decrementCount(); setLineTotal(item.price * itemCount) }} />
          </ProductAmountContainer>
          <ProductPrice>$ {item.price * itemCount}</ProductPrice>
        </PriceDetail>
      </Product>
    </div>
  );
};

export default CartItem;

这是Cart组件:

const Cart = () => {
  var [total, setTotal] = useState(0);

  const handleTotal = (id, price) => {
    setTotal(total + price);
  };

  return (
    <Container>
      <Navbar />
      <Announcement />
      <Wrapper>
        <Title>YOUR BAG</Title>
        <Top>
          <TopButton>CONTINUE SHOPPING</TopButton>
          <TopTexts>
            <TopText>购物袋(2)</TopText>
            <TopText>愿望清单(0)</TopText>
          </TopTexts>
          <TopButton type="filled">立即结账</TopButton>
        </Top>
        <Bottom>
          <Info>
            {IntheCart.map((item) => (
              <CartItem key={item.id} item={item} handleTotal={handleTotal} />
            ))}
            <Hr />
          </Info>
          <Summary>
            <SummaryTitle>订单摘要</SummaryTitle>
            <SummaryItem>
              <SummaryItemText>小计</SummaryItemText>
              <SummaryItemPrice>$ {total}</SummaryItemPrice>
            </SummaryItem>
            <SummaryItem>
              <SummaryItemText>预计运费</SummaryItemText>
              <SummaryItemPrice>$ 5.90</SummaryItemPrice>
            </SummaryItem>
            <SummaryItem>
              <SummaryItemText>运费折扣</SummaryItemText>
              <SummaryItemPrice>$ -5.90</SummaryItemPrice>
            </SummaryItem>
            <SummaryItem type="total">
              <SummaryItemText>总计</SummaryItemText>
              <SummaryItemPrice>$ {total + 5.90}</SummaryItemPrice>
            </SummaryItem>
            <Button>立即结账</Button>
          </Summary>
        </Bottom>
      </Wrapper>
      <Footer />
    </Container>
  );
};

export default Cart;
英文:

I have two react components one is Cart and the other is CartItem, Inside Cart I am looping using .map the CartItem. Inside CartItem I have a line total which is price * item.count. How can I sum up all the line totals regardless how many CartItems I have, and return the Total so that I can have the overall value of the cart.
I tried to add a handle total function but its only returning line total of one element not all of them.

Here is the CartItem:

const CartItem = ({item, handleTotal}) =&gt; {
var [itemCount, SetItemCount] = useState(1);
var [Linetotal, SetLineTotal] = useState(item.price);
const incrementcount = () =&gt; {
SetItemCount(++itemCount);
};
const decrementcount = () =&gt; {
SetItemCount(--itemCount);
};
useEffect(() =&gt; {
handleTotal(item.id,Linetotal)
},[])
return (
&lt;div&gt;
&lt;Product&gt;
&lt;ProductDetail&gt;
&lt;Image src={item.image} /&gt;
&lt;Details&gt;
&lt;ProductName&gt;
&lt;b&gt;Product:&lt;/b&gt; {item.name}
&lt;/ProductName&gt;
&lt;ProductId&gt;
&lt;b&gt;ID:&lt;/b&gt; {item.id}
&lt;/ProductId&gt;
&lt;ProductColor color={item.color} /&gt;
&lt;ProductSize&gt;
&lt;b&gt;Size:&lt;/b&gt; {item.size}
&lt;/ProductSize&gt;
&lt;/Details&gt;
&lt;/ProductDetail&gt;
&lt;PriceDetail&gt;
&lt;ProductAmountContainer&gt;
&lt;Add onClick={() =&gt; {incrementcount(); SetLineTotal(item.price*itemCount)}} /&gt;
&lt;ProductAmount&gt;{itemCount}&lt;/ProductAmount&gt;
&lt;Remove onClick={() =&gt; {decrementcount(); SetLineTotal(item.price*itemCount)}} /&gt;
&lt;/ProductAmountContainer&gt;
&lt;ProductPrice&gt;$ {item.price*itemCount}&lt;/ProductPrice&gt;
&lt;/PriceDetail&gt;
&lt;/Product&gt;
&lt;/div&gt;
);
};
export default CartItem;

and Here is the Cart:

const Cart = () =&gt; {
var [total, setTotal] = useState([]);
const handleTotal = (id,price) =&gt; {
setTotal(id,price);
};
return (
&lt;Container&gt;
&lt;Navbar /&gt;
&lt;Announcement /&gt;
&lt;Wrapper&gt;
&lt;Title&gt;YOUR BAG&lt;/Title&gt;
&lt;Top&gt;
&lt;TopButton&gt;CONTINUE SHOPPING&lt;/TopButton&gt;
&lt;TopTexts&gt;
&lt;TopText&gt;Shopping Bag(2)&lt;/TopText&gt;
&lt;TopText&gt;Your Wishlist (0)&lt;/TopText&gt;
&lt;/TopTexts&gt;
&lt;TopButton type=&quot;filled&quot;&gt;CHECKOUT NOW&lt;/TopButton&gt;
&lt;/Top&gt;
&lt;Bottom&gt;
&lt;Info&gt;
{IntheCart.map((item) =&gt; (
&lt;CartItem key={item.id} item={item} handleTotal={handleTotal} /&gt;
))}
&lt;Hr /&gt;
&lt;/Info&gt;
&lt;Summary&gt;
&lt;SummaryTitle&gt;ORDER SUMMARY&lt;/SummaryTitle&gt;
&lt;SummaryItem&gt;
&lt;SummaryItemText&gt;Subtotal&lt;/SummaryItemText&gt;
&lt;SummaryItemPrice&gt;$ 80&lt;/SummaryItemPrice&gt;
&lt;/SummaryItem&gt;
&lt;SummaryItem&gt;
&lt;SummaryItemText&gt;Estimated Shipping&lt;/SummaryItemText&gt;
&lt;SummaryItemPrice&gt;$ 5.90&lt;/SummaryItemPrice&gt;
&lt;/SummaryItem&gt;
&lt;SummaryItem&gt;
&lt;SummaryItemText&gt;Shipping Discount&lt;/SummaryItemText&gt;
&lt;SummaryItemPrice&gt;$ -5.90&lt;/SummaryItemPrice&gt;
&lt;/SummaryItem&gt;
&lt;SummaryItem type=&quot;total&quot;&gt;
&lt;SummaryItemText&gt;Total&lt;/SummaryItemText&gt;
&lt;SummaryItemPrice&gt;$ 80&lt;/SummaryItemPrice&gt;
&lt;/SummaryItem&gt;
&lt;Button&gt;CHECKOUT NOW&lt;/Button&gt;
&lt;/Summary&gt;
&lt;/Bottom&gt;
&lt;/Wrapper&gt;
&lt;Footer /&gt;
&lt;/Container&gt;
);
};
export default Cart;

答案1

得分: 1

你可以在 Card 组件中创建 updateTotal 函数,然后在 CardItem 中的 incresedecrement 项目时更新 total 值。

const CartItem = ({item, handleTotal, updateTotal}) => {
// 代码...
const incrementcount = () => {
  SetItemCount(++itemCount);
  updateTotal(item.price);
};

const decrementcount = () => {
  SetItemCount(--itemCount);
  updateTotal(-item.price);
};
// 代码...

updateTotal 函数。

var [totalPrice, setTotalPrice] = useState(0);

const updateTotal = (value) => {
  setTotalPrice(prev => prev + value)
} 

updateTotal 函数添加到 CardItem

<CartItem key={item.id} item={item} handleTotal={handleTotal} updateTotal={updateTotal} />
英文:

You can create updateTotal function in the Card component and once you increse or decrement item in the CardItem update the total value.

const CartItem = ({item, handleTotal, updateTotal}) =&gt; {
// code...
const incrementcount = () =&gt; {
SetItemCount(++itemCount);
updateTotal(item.price);
};
const decrementcount = () =&gt; {
SetItemCount(--itemCount);
updateTotal(-item.price);
};
// code...

updateTotal function.

var [totalPrice, setTotalPrice] = useState(0);
const updateTotal = (value) =&gt; {
setTotalPrice(prev =&gt; prev + value)
} 

Add the updateTotal function to CardItem

 &lt;CartItem key={item.id} item={item} handleTotal={handleTotal} updateTotal={updateTotal} /&gt;

答案2

得分: 1

如果您需要将子总和添加到总和中,可以按照以下方式操作。

    const Cart = () => {
      ...
    
      var [subSum, setSubSum] = useState(null);
      var [totalSum, setTotalSum] = useState(0);
      
      const handleTotal = (id, price) => {
        setSubSum({ ...subSum, id: price });  
      };
      useEffect(() => {
        var sum = 0;
        for (const [key, value] of Object.entries(subSum)) {
           sum += value;
        }
        setTotalSum(sum);
      }, [totalSum])
    
      ...
    }
英文:

If you need sub sum to so sub total, you can do like this.

const Cart = () =&gt; {
...
var [subSum, setSubSum] = useState(null);
var [totalSum, setTotalSum] = useState(0);
const handleTotal = (id,price) =&gt; {
setSubSum({...subSum, id:price});  
};
useEffect(()=&gt;{
var sum = 0;
for (const [key, value] of Object.entries(subSum)) {
sum += value;
}
setTotalSum(sum);
},[total])
...
}

huangapple
  • 本文由 发表于 2023年2月18日 16:23:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75492078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定