如何累积 FieldArray 输入的值(formik + React)

问题描述 投票:0回答:1

我有一个包含商品详细信息的 FieldArray - 数量和单价。在FieldArray之外,我有一个total_all输入(已禁用,仅供用户查看所有商品的总价)。

我想计算total_all,但它没有得到所有商品的total_price。如果我创建 2 个商品,它将仅采用最新更新商品的 Total_price 值。我知道发生这种情况是因为我的代码总是会覆盖以前的值。

如何获取所有商品的total_price总和,以便我可以为total_all设置FieldValue?

商品单价

<Form.Control                              
                              name={`item.${index}.unit_price`}
                              type="number"                              
                              onChange={(event) => {
                                const { value } = event.target;
                                const newUnitPrice = parseFloat(value);
                                const quantity = parseFloat(item.quantity);
                                const totalPrice =
                                  isNaN(quantity) || isNaN(newUnitPrice)
                                    ? ""
                                    : (quantity * newUnitPrice).toFixed(2);
                                let total_price_all = "";
                                total_price_all = total_price_all + totalPrice;
                                setFieldValue("total_all", total_price_all);

                                setFieldValue(
                                  `item.${index}.unit_price`,
                                  newUnitPrice
                                );
                                setFieldValue(
                                  `item.${index}.total_price`,
                                  totalPrice
                                );
                              }}
                              value={item.unit_price || ""}
                            />

商品数量

<Form.Control                              
                              name={`item.${index}.quantity`}
                              type="number"
                              value={item.quantity || ""}                              
                              onChange={(event) => {
                                const { value } = event.target;
                                const newQuantity = parseFloat(value);
                                const unitPrice = parseFloat(item.unit_price);
                                const totalPrice =
                                  isNaN(newQuantity) || isNaN(unitPrice)
                                    ? ""
                                    : (newQuantity * unitPrice).toFixed(2);
                                let total_price_all = "";
                                total_price_all = total_price_all + totalPrice;
                                setFieldValue("total_all", total_price_all);

                                setFieldValue(
                                  `item.${index}.quantity`,
                                  newQuantity
                                );
                                setFieldValue(
                                  `item.${index}.total_price`,
                                  totalPrice
                                );
                              }}
                            />

商品总价

<Form.Control
                              name={`item.${index}.total_price`}
                              type="text"
                              value={item.total_price || ""}                              
                              disabled
                            />

所有商品的价格(FieldArray 之外)

<Form.Label column lg={3} className="float-start">
                Total Price All Items (RM)
              </Form.Label>
              <Col lg={3}>
                <Form.Control
                  name="total_all"
                  type="text"
                  value={values.total_all || ""}
                  disabled
                />
reactjs formik
1个回答
0
投票

要正确计算所有商品的总价,您需要迭代

FieldArray
中的所有商品并将其总价相加。您可以通过以下方式修改代码来实现此目的:

import { useEffect } from "react";

// Assuming this is within your component function...

// Add a useEffect hook to recalculate total_all whenever items change
useEffect(() => {
  const totalAll = values.item.reduce((total, currentItem) => {
    const totalPrice = parseFloat(currentItem.total_price);
    return total + (isNaN(totalPrice) ? 0 : totalPrice);
  }, 0);
  setFieldValue("total_all", totalAll.toFixed(2));
}, [values.item]);

// Modify your onChange handlers to only update item fields

<Form.Control                              
  name={`item.${index}.unit_price`}
  type="number"                              
  onChange={(event) => {
    const { value } = event.target;
    const newUnitPrice = parseFloat(value);
    const quantity = parseFloat(item.quantity);
    const totalPrice = isNaN(quantity) || isNaN(newUnitPrice) ? "" : (quantity * newUnitPrice).toFixed(2);
    
    setFieldValue(`item.${index}.unit_price`, newUnitPrice);
    setFieldValue(`item.${index}.total_price`, totalPrice);
  }}
  value={item.unit_price || ""}
/>

<Form.Control                              
  name={`item.${index}.quantity`}
  type="number"
  value={item.quantity || ""}                              
  onChange={(event) => {
    const { value } = event.target;
    const newQuantity = parseFloat(value);
    const unitPrice = parseFloat(item.unit_price);
    const totalPrice = isNaN(newQuantity) || isNaN(unitPrice) ? "" : (newQuantity * unitPrice).toFixed(2);
    
    setFieldValue(`item.${index}.quantity`, newQuantity);
    setFieldValue(`item.${index}.total_price`, totalPrice);
  }}
/>

<Form.Control
  name={`item.${index}.total_price`}
  type="text"
  value={item.total_price || ""}
  disabled
/>

<Form.Label column lg={3} className="float-start">
  Total Price All Items (RM)
</Form.Label>
<Col lg={3}>
  <Form.Control
    name="total_all"
    type="text"
    value={values.total_all || ""}
    disabled
  />
</Col>

通过这些修改,只要任何商品的总价或数量发生变化,所有商品的总价都将重新计算。这可确保

total_all
字段反映所有商品的正确总价。

© www.soinside.com 2019 - 2024. All rights reserved.