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

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

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组件:

  1. const CartItem = ({ item, handleTotal }) => {
  2. var [itemCount, setItemCount] = useState(1);
  3. var [lineTotal, setLineTotal] = useState(item.price);
  4. const incrementCount = () => {
  5. setItemCount(++itemCount);
  6. };
  7. const decrementCount = () => {
  8. setItemCount(--itemCount);
  9. };
  10. useEffect(() => {
  11. handleTotal(item.id, lineTotal);
  12. }, []);
  13. return (
  14. <div>
  15. <Product>
  16. <ProductDetail>
  17. <Image src={item.image} />
  18. <Details>
  19. <ProductName>
  20. <b>产品</b> {item.name}
  21. </ProductName>
  22. <ProductId>
  23. <b>ID</b> {item.id}
  24. </ProductId>
  25. <ProductColor color={item.color} />
  26. <ProductSize>
  27. <b>尺码</b> {item.size}
  28. </ProductSize>
  29. </Details>
  30. </ProductDetail>
  31. <PriceDetail>
  32. <ProductAmountContainer>
  33. <Add onClick={() => { incrementCount(); setLineTotal(item.price * itemCount) }} />
  34. <ProductAmount>{itemCount}</ProductAmount>
  35. <Remove onClick={() => { decrementCount(); setLineTotal(item.price * itemCount) }} />
  36. </ProductAmountContainer>
  37. <ProductPrice>$ {item.price * itemCount}</ProductPrice>
  38. </PriceDetail>
  39. </Product>
  40. </div>
  41. );
  42. };
  43. export default CartItem;

这是Cart组件:

  1. const Cart = () => {
  2. var [total, setTotal] = useState(0);
  3. const handleTotal = (id, price) => {
  4. setTotal(total + price);
  5. };
  6. return (
  7. <Container>
  8. <Navbar />
  9. <Announcement />
  10. <Wrapper>
  11. <Title>YOUR BAG</Title>
  12. <Top>
  13. <TopButton>CONTINUE SHOPPING</TopButton>
  14. <TopTexts>
  15. <TopText>购物袋(2)</TopText>
  16. <TopText>愿望清单(0)</TopText>
  17. </TopTexts>
  18. <TopButton type="filled">立即结账</TopButton>
  19. </Top>
  20. <Bottom>
  21. <Info>
  22. {IntheCart.map((item) => (
  23. <CartItem key={item.id} item={item} handleTotal={handleTotal} />
  24. ))}
  25. <Hr />
  26. </Info>
  27. <Summary>
  28. <SummaryTitle>订单摘要</SummaryTitle>
  29. <SummaryItem>
  30. <SummaryItemText>小计</SummaryItemText>
  31. <SummaryItemPrice>$ {total}</SummaryItemPrice>
  32. </SummaryItem>
  33. <SummaryItem>
  34. <SummaryItemText>预计运费</SummaryItemText>
  35. <SummaryItemPrice>$ 5.90</SummaryItemPrice>
  36. </SummaryItem>
  37. <SummaryItem>
  38. <SummaryItemText>运费折扣</SummaryItemText>
  39. <SummaryItemPrice>$ -5.90</SummaryItemPrice>
  40. </SummaryItem>
  41. <SummaryItem type="total">
  42. <SummaryItemText>总计</SummaryItemText>
  43. <SummaryItemPrice>$ {total + 5.90}</SummaryItemPrice>
  44. </SummaryItem>
  45. <Button>立即结账</Button>
  46. </Summary>
  47. </Bottom>
  48. </Wrapper>
  49. <Footer />
  50. </Container>
  51. );
  52. };
  53. 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:

  1. const CartItem = ({item, handleTotal}) =&gt; {
  2. var [itemCount, SetItemCount] = useState(1);
  3. var [Linetotal, SetLineTotal] = useState(item.price);
  4. const incrementcount = () =&gt; {
  5. SetItemCount(++itemCount);
  6. };
  7. const decrementcount = () =&gt; {
  8. SetItemCount(--itemCount);
  9. };
  10. useEffect(() =&gt; {
  11. handleTotal(item.id,Linetotal)
  12. },[])
  13. return (
  14. &lt;div&gt;
  15. &lt;Product&gt;
  16. &lt;ProductDetail&gt;
  17. &lt;Image src={item.image} /&gt;
  18. &lt;Details&gt;
  19. &lt;ProductName&gt;
  20. &lt;b&gt;Product:&lt;/b&gt; {item.name}
  21. &lt;/ProductName&gt;
  22. &lt;ProductId&gt;
  23. &lt;b&gt;ID:&lt;/b&gt; {item.id}
  24. &lt;/ProductId&gt;
  25. &lt;ProductColor color={item.color} /&gt;
  26. &lt;ProductSize&gt;
  27. &lt;b&gt;Size:&lt;/b&gt; {item.size}
  28. &lt;/ProductSize&gt;
  29. &lt;/Details&gt;
  30. &lt;/ProductDetail&gt;
  31. &lt;PriceDetail&gt;
  32. &lt;ProductAmountContainer&gt;
  33. &lt;Add onClick={() =&gt; {incrementcount(); SetLineTotal(item.price*itemCount)}} /&gt;
  34. &lt;ProductAmount&gt;{itemCount}&lt;/ProductAmount&gt;
  35. &lt;Remove onClick={() =&gt; {decrementcount(); SetLineTotal(item.price*itemCount)}} /&gt;
  36. &lt;/ProductAmountContainer&gt;
  37. &lt;ProductPrice&gt;$ {item.price*itemCount}&lt;/ProductPrice&gt;
  38. &lt;/PriceDetail&gt;
  39. &lt;/Product&gt;
  40. &lt;/div&gt;
  41. );
  42. };
  43. export default CartItem;

and Here is the Cart:

  1. const Cart = () =&gt; {
  2. var [total, setTotal] = useState([]);
  3. const handleTotal = (id,price) =&gt; {
  4. setTotal(id,price);
  5. };
  6. return (
  7. &lt;Container&gt;
  8. &lt;Navbar /&gt;
  9. &lt;Announcement /&gt;
  10. &lt;Wrapper&gt;
  11. &lt;Title&gt;YOUR BAG&lt;/Title&gt;
  12. &lt;Top&gt;
  13. &lt;TopButton&gt;CONTINUE SHOPPING&lt;/TopButton&gt;
  14. &lt;TopTexts&gt;
  15. &lt;TopText&gt;Shopping Bag(2)&lt;/TopText&gt;
  16. &lt;TopText&gt;Your Wishlist (0)&lt;/TopText&gt;
  17. &lt;/TopTexts&gt;
  18. &lt;TopButton type=&quot;filled&quot;&gt;CHECKOUT NOW&lt;/TopButton&gt;
  19. &lt;/Top&gt;
  20. &lt;Bottom&gt;
  21. &lt;Info&gt;
  22. {IntheCart.map((item) =&gt; (
  23. &lt;CartItem key={item.id} item={item} handleTotal={handleTotal} /&gt;
  24. ))}
  25. &lt;Hr /&gt;
  26. &lt;/Info&gt;
  27. &lt;Summary&gt;
  28. &lt;SummaryTitle&gt;ORDER SUMMARY&lt;/SummaryTitle&gt;
  29. &lt;SummaryItem&gt;
  30. &lt;SummaryItemText&gt;Subtotal&lt;/SummaryItemText&gt;
  31. &lt;SummaryItemPrice&gt;$ 80&lt;/SummaryItemPrice&gt;
  32. &lt;/SummaryItem&gt;
  33. &lt;SummaryItem&gt;
  34. &lt;SummaryItemText&gt;Estimated Shipping&lt;/SummaryItemText&gt;
  35. &lt;SummaryItemPrice&gt;$ 5.90&lt;/SummaryItemPrice&gt;
  36. &lt;/SummaryItem&gt;
  37. &lt;SummaryItem&gt;
  38. &lt;SummaryItemText&gt;Shipping Discount&lt;/SummaryItemText&gt;
  39. &lt;SummaryItemPrice&gt;$ -5.90&lt;/SummaryItemPrice&gt;
  40. &lt;/SummaryItem&gt;
  41. &lt;SummaryItem type=&quot;total&quot;&gt;
  42. &lt;SummaryItemText&gt;Total&lt;/SummaryItemText&gt;
  43. &lt;SummaryItemPrice&gt;$ 80&lt;/SummaryItemPrice&gt;
  44. &lt;/SummaryItem&gt;
  45. &lt;Button&gt;CHECKOUT NOW&lt;/Button&gt;
  46. &lt;/Summary&gt;
  47. &lt;/Bottom&gt;
  48. &lt;/Wrapper&gt;
  49. &lt;Footer /&gt;
  50. &lt;/Container&gt;
  51. );
  52. };
  53. export default Cart;

答案1

得分: 1

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

  1. const CartItem = ({item, handleTotal, updateTotal}) => {
  2. // 代码...
  3. const incrementcount = () => {
  4. SetItemCount(++itemCount);
  5. updateTotal(item.price);
  6. };
  7. const decrementcount = () => {
  8. SetItemCount(--itemCount);
  9. updateTotal(-item.price);
  10. };
  11. // 代码...

updateTotal 函数。

  1. var [totalPrice, setTotalPrice] = useState(0);
  2. const updateTotal = (value) => {
  3. setTotalPrice(prev => prev + value)
  4. }

updateTotal 函数添加到 CardItem

  1. <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.

  1. const CartItem = ({item, handleTotal, updateTotal}) =&gt; {
  2. // code...
  3. const incrementcount = () =&gt; {
  4. SetItemCount(++itemCount);
  5. updateTotal(item.price);
  6. };
  7. const decrementcount = () =&gt; {
  8. SetItemCount(--itemCount);
  9. updateTotal(-item.price);
  10. };
  11. // code...

updateTotal function.

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

Add the updateTotal function to CardItem

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

答案2

得分: 1

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

  1. const Cart = () => {
  2. ...
  3. var [subSum, setSubSum] = useState(null);
  4. var [totalSum, setTotalSum] = useState(0);
  5. const handleTotal = (id, price) => {
  6. setSubSum({ ...subSum, id: price });
  7. };
  8. useEffect(() => {
  9. var sum = 0;
  10. for (const [key, value] of Object.entries(subSum)) {
  11. sum += value;
  12. }
  13. setTotalSum(sum);
  14. }, [totalSum])
  15. ...
  16. }
英文:

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

  1. const Cart = () =&gt; {
  2. ...
  3. var [subSum, setSubSum] = useState(null);
  4. var [totalSum, setTotalSum] = useState(0);
  5. const handleTotal = (id,price) =&gt; {
  6. setSubSum({...subSum, id:price});
  7. };
  8. useEffect(()=&gt;{
  9. var sum = 0;
  10. for (const [key, value] of Object.entries(subSum)) {
  11. sum += value;
  12. }
  13. setTotalSum(sum);
  14. },[total])
  15. ...
  16. }

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:

确定