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

如何在Redux Form中实现两字段onChange求和并显示在第三字段

Fixing Redux-Form Real-Time Sum Calculation with onChange

Hey there! Let's sort out this real-time sum issue you're facing with Redux-Form. The problem you described—where entering 12 + 13 gives 27 instead of 25—happens because your global variable was accumulating every intermediate input value (e.g., when typing "12", it adds 1 first, then 12, same for "13"). Instead of relying on a global variable, we need to pull the current full values of both fields every time either changes, then recalculate the sum from scratch.

Here's a step-by-step solution:

1. Use Redux-Form's Selectors to Get Field Values

First, we'll use formValueSelector to fetch the latest values of clientIncome and partnerIncome from the Redux store. This ensures we always have the complete current value of each field, not just the incremental input.

2. Recalculate Sum on Field Change

Whenever either field updates, we'll take their current values, convert them to numbers, sum them, and update the total field using Redux-Form's change action.

Full Code Example

import React, { Component } from 'react';
import { Field, reduxForm, formValueSelector, change } from 'redux-form';
import { connect } from 'react-redux';

// Replace with your actual form name
const FORM_NAME = 'incomeForm';

class IncomeForm extends Component {
  // Calculate total and update the total field
  updateTotal = () => {
    const { clientIncome, partnerIncome, dispatch } = this.props;
    
    // Convert values to numbers, default to 0 if empty/non-numeric
    const clientNum = parseFloat(clientIncome) || 0;
    const partnerNum = parseFloat(partnerIncome) || 0;
    const total = clientNum + partnerNum;
    
    // Dispatch action to update the totalIncome field
    dispatch(change(FORM_NAME, 'totalIncome', total.toString()));
  };

  // Trigger recalculation whenever either income field changes
  componentDidUpdate(prevProps) {
    const { clientIncome, partnerIncome } = this.props;
    if (clientIncome !== prevProps.clientIncome || partnerIncome !== prevProps.partnerIncome) {
      this.updateTotal();
    }
  }

  render() {
    return (
      <form>
        <div>
          <label>Client Income</label>
          <Field
            name="clientIncome"
            component="input"
            type="number"
            placeholder="Enter client income"
          />
        </div>
        <div>
          <label>Partner Income</label>
          <Field
            name="partnerIncome"
            component="input"
            type="number"
            placeholder="Enter partner income"
          />
        </div>
        <div>
          <label>Total Income</label>
          <Field
            name="totalIncome"
            component="input"
            type="text"
            disabled // Make total field read-only
          />
        </div>
      </form>
    );
  }
}

// Selector to get current field values from the store
const selector = formValueSelector(FORM_NAME);
const mapStateToProps = state => ({
  clientIncome: selector(state, 'clientIncome'),
  partnerIncome: selector(state, 'partnerIncome'),
});

// Connect form and Redux store
export default connect(mapStateToProps)(reduxForm({ form: FORM_NAME })(IncomeForm));

Key Notes:

  • No Global Variables: We avoid global state by pulling values directly from the Redux store, which holds the latest complete values of each form field.
  • Robust Number Handling: Using parseFloat(...) || 0 ensures empty inputs or non-numeric values don't break the calculation (they'll be treated as 0).
  • Real-Time Updates: The componentDidUpdate lifecycle method triggers the sum recalculation whenever either income field changes, which works perfectly with onChange (since Redux-Form updates the store on every keystroke).

Alternatively, if you prefer handling it directly in the Field's onChange prop (instead of componentDidUpdate), you can modify each field like this:

<Field
  name="clientIncome"
  component="input"
  type="number"
  onChange={(e, newValue) => {
    // First update the field's value in the store
    this.props.input.onChange(newValue);
    // Then recalculate the total
    this.updateTotal();
  }}
/>

This achieves the same result—pick whichever approach feels cleaner for your codebase!

内容的提问来源于stack exchange,提问作者Polly Banerjee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:19:12