You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux-form FieldArray中total字段值求和方案咨询

解决React Final Form中FieldArray动态项的total求和问题

Got it, let's break down how to calculate the sum of total fields from a dynamic FieldArray in React Final Form. The key here is that you don't need to target each index explicitly—you can grab the entire array of items and compute the sum directly. Here are a few reliable approaches:

方法1:使用form.getValues()实时计算

The form object (available via the useForm hook or passed in the render prop of the Form component) lets you fetch the entire test array at once. Pair this with useMemo to avoid recalculating on every render unless the array changes.

import { Form, FieldArray, useForm } from 'react-final-form';
import React from 'react';

function DynamicSumForm() {
  const form = useForm();

  // Memoize the total to optimize performance
  const testTotal = React.useMemo(() => {
    // Get the entire test array, default to empty array if it doesn't exist
    const testItems = form.getValues('test') || [];
    // Reduce the array to sum up all total values (handle empty/non-number cases)
    return testItems.reduce((accumulator, item) => {
      const numericTotal = Number(item.total);
      return accumulator + (isNaN(numericTotal) ? 0 : numericTotal);
    }, 0);
  }, [form]);

  return (
    <Form
      initialValues={{ test: [{ total: 0 }] }}
      onSubmit={(values) => {
        console.log('Submitted values:', values);
        console.log('Calculated total:', testTotal);
      }}
      render={({ handleSubmit }) => (
        <form onSubmit={handleSubmit}>
          <FieldArray name="test">
            {({ fields }) => (
              <div>
                {fields.map((name, index) => (
                  <div key={name} className="item-row">
                    <label>Item {index + 1} Total:</label>
                    <Field name={`${name}.total`} type="number" placeholder="0" />
                    <button
                      type="button"
                      onClick={() => fields.remove(index)}
                      disabled={fields.length === 1}
                    >
                      Remove
                    </button>
                  </div>
                ))}
                <button type="button" onClick={() => fields.push({ total: 0 })}>
                  Add New Item
                </button>
              </div>
            )}
          </FieldArray>

          <div className="total-display">
            <strong>Total Sum:</strong> {testTotal}
          </div>

          <button type="submit">Submit Form</button>
        </form>
      )}
    />
  );
}

方法2:使用formValueSelector获取整个数组

You mentioned formValueSelector works well for explicit fields—good news: it can also fetch the entire test array. Just pass the root array name (test) to the selector, then process the array to calculate the sum.

import { Form, FieldArray, formValueSelector, useFormState } from 'react-final-form';
import React from 'react';

// Create a selector tied to your form (use the Form's `name` prop if you set one)
const formSelector = formValueSelector('dynamic-sum-form');

function TotalDisplay() {
  // Get the current form state
  const formState = useFormState();
  // Fetch the entire test array from form state
  const testItems = formSelector(formState, 'test') || [];
  
  const testTotal = testItems.reduce((sum, item) => {
    const total = Number(item.total);
    return sum + (isNaN(total) ? 0 : total);
  }, 0);

  return <p><strong>Total:</strong> {testTotal}</p>;
}

// Use TotalDisplay inside your Form component
function MyForm() {
  return (
    <Form
      name="dynamic-sum-form"
      initialValues={{ test: [{ total: 0 }] }}
      onSubmit={(values) => console.log(values)}
      render={({ handleSubmit }) => (
        <form onSubmit={handleSubmit}>
          <FieldArray name="test">
            {/* ... your field array items ... */}
          </FieldArray>
          <TotalDisplay />
          <button type="submit">Submit</button>
        </form>
      )}
    />
  );
}

关键注意事项

  • Handle empty/non-number values: Always convert item.total to a number and check for NaN—this prevents unexpected NaN results if the field is empty or has non-numeric input.
  • Memoization: Use useMemo (in function components) to avoid recalculating the sum on every render, which improves performance especially with large arrays.
  • Form state updates: Both methods will automatically update the sum whenever the test array changes (when you add/remove items or edit a total field), since they depend on form state.

内容的提问来源于stack exchange,提问作者Shawn Matthews

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:43:15