redux-form - 使用onChange使用其他2个字段值计算字段值

时间:2017-03-28 14:32:50

标签: javascript forms reactjs redux-form

场景:

考虑3个字段:quantitysinglePricetotalPrice。 我需要所有这些都是我的形式的字段,但每次我用一个你可以想象的简单操作改变数量或singlePrice时,必须重新计算totalPrice ..

我做了什么:

  • 创建了一个由数量字段的onChange事件触发的函数,另一个函数触发了singlePrice字段。

  • 上面的函数调用带有这样的有效负载的redux动作:

    { name: name_of_the_updated_field, value: new_field_value }

  • 操作由formReducer plugin选取,进行计算并返回更新后的值对象。

问题: 我的redux商店没有更新,也没有我的表格。

我的表单缩减器(我必须更新的属性位于另一个属性中)。

import { reducer as formReducer } from 'redux-form';

export default formReducer.plugin({
  formName: (state, action) => {
    switch (action.type) {
      case 'CALC_TOTAL_PRICE':
        return {
          ...state,
          values: {
            ...state.values,
            competences: state.values.competences.map((c, i) => {
              if (i === action.payload.index) {
                const { name, value } = action.payload;
                const next = Object.assign({}, c);
                next[name] = value;
                next.totalPrice = next.quantity * next.singlePrice
                return next;
              }
              return c;
            }),
          },
        };
      default:
        return state;
    }
  },
});

我错过了什么吗?如何解决这个问题? 有一个更简单的方法来获得这个结果吗?

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

您可能会考虑使用formValueSelector来获取当前输入值并计算总数 -

import React, { PropTypes } from 'react';
import { Field, reduxForm, formValueSelector, FieldArray, SubmissionError } from 'redux-form';
import { connect } from 'react-redux';

class NewSaleForm extends React.Component {

   componentWillReceiveProps(nextProps) {
      if (nextProps.items && nextProps.items.length > 0) {
         nextProps.items.forEach((item) => {
            if (item.price && item.unit) {
               if (item.unit_discount) {
                  item.total = (item.price - item.unit_discount) * item.unit;
               } else {
                  item.total = item.price * item.unit;
               }
            } else {
               item.total = '';
            }
         });
      }
   }

render() {
   ......
}


NewSaleForm = reduxForm({ // eslint-disable-line
   form: 'newSaleForm'
})(NewSaleForm);

const selector = formValueSelector('newSaleForm');

NewSaleForm = connect(state => { // eslint-disable-line
   const items = selector(state, 'items');
   return {
      items,
   };
})(NewSaleForm);

export default NewSaleForm;