从 .map() 的先前填充值计算新值

Calculate New Value From Previous populated value from .map()

我正在使用 .map() 函数在 React Js 中制作一个 Table。在 table 的最后 <td> 中,我正在通过函数计算产品的税额。此金额填写为他们指定的每一行 <td>


 {
          (!cr.items.length < 1) &&
           cr.items.map((item , ind) => {
               return(
                      <td scope="col">{(item) ? taxedValue(item.quantity , item.salesInfo.unitPrice , item.discount , item.tax) :null}</td>
                 </tr>
                 )
        })
 }

函数taxedValuereturn新金额。可以有很多行。我想要的是获取所有先前 taxedValue 行的总和。

就像映射 return 这些行

<tr><td>1<td></td>
<tr><td>2<td></td>

我想添加 {1+2} = 3(//将其作为我的总数以在代码中的任何位置访问它//} 我尝试调用初始值为 0 的状态函数。但出现错误 Too much re-render.

我认为您可以在单独的函数中执行此操作以保持该逻辑独立。您可以做的是定义一个变量并在 map 的每次迭代中递增该值,然后在最后一个元素中呈现一个附加列。像这样:

const renderColumns = () => {
  let total = 0;

  if (!cr.items.length < 1) {
    return cr.items.map((item , ind) => {
      const value = item ? taxedValue(item.quantity , item.salesInfo.unitPrice , item.discount , item.tax) : null;
      total += value || 0;

      return (
        <>
          <td scope="col">{value}</td>
          {ind === cr.items.length - 1 ? (
            <td>{total}</td>
          ) : null}
        </>
      );
    });
  }

  return null;
};

array.prototype.map 函数中简单地添加一个总和会很容易,但是这个回调是一个没有副作用的纯函数。

我建议只使用 array.prototype.reduce 单独计算总数。如果每个渲染周期计算两次税值是令人望而却步的,那么重构代码以计算一次税值并将其注入到您要映射的数据中 将其添加到总和。

const computeTotalTaxedValue = cr.items.reduce(
  (total, item) => item ? taxedValue(item.quantity, item.salesInfo.unitPrice, item.discount, item.tax) : 0,
  0,
);

如果每个渲染周期为每个项目计算两次税值是令人望而却步的,那么计算一次并将其注入数据并计算总和。

const [totalTaxedValue, setTotalTaxedValue] = useState(0);
const [taxedValues, setTaxedValues] = useState([]);

useEffect(() => {
  let totalTaxedValue = 0;
  const taxedValues = [];

  cr.items.forEach(item => {
    const taxValue = item ? taxedValue(item.quantity, item.salesInfo.unitPrice, item.discount, item.tax) : null;
    totalTaxedValue += taxValue;
    taxedValues.push(taxValue);
  });

  setTotalTaxedValue(totalTaxedValue);
  setTaxedValues(taxedValues);
}, [cr.items]);

...

{
  (!taxedValues.length < 1) &&
  taxedValues.map((taxValue, ind) => <td scope="col">{taxValue}</td>
  })
}