Как использовать вычисляемые поля response-final-from с массивом объектов

У меня есть массив объектов в react-final-form с полем sum. В конце я хотел бы подсчитать сумму всех сумм. Итак, я использую вычисляемые поля из final-form-calculate вот так:

const calculator = createDecorator({
  field: /day\[\d\]\.sum/, // when a field matching this pattern changes...
  updates: (value, name, allValues) => {
    console.log("Updated field", value, name);
    // ...update the total to the result of this function
    total: (ignoredValue, allValues) =>
      (allValues.day || []).reduce((sum, value) => sum + Number(value || 0), 0);
    return {};
  }
});

Когда я ввожу значения во входные данные, вызывается console.log, но общая сумма не обновляется. Думаю, он не выбирает значения из необходимых полей. Как я могу это исправить? Вот мои коды и ящик https://codesandbox.io/s/react-final-form-calculated-fields-hkd65?fontsize=14.


person jupiteror    schedule 18.10.2019    source источник


Ответы (2)


У вас есть синтаксическая ошибка во фрагменте кода, в частности в функции калькулятора. Эта версия функции работает:

const calculator = createDecorator({
  field: /day\[\d\]\.sum/, // when a field matching this pattern changes...
  updates:  {
    // ...update the total to the result of this function
    total: (ignoredValue, allValues) => (allValues.day || []).reduce((sum, value) => sum + Number(value.sum || 0), 0),
  }
});

Я сделал два основных изменения:

  • В обратном вызове сокращения я изменил Number(value || 0) на Number(value.sum || 0)
  • Я также установил свойство updates для объекта вместо функции.
person Tunmee    schedule 18.10.2019

Окончательная форма-вычисление документов, скажем, средство обновления может быть:

Либо объект функций средства обновления, либо функция, которая генерирует обновления для нескольких полей.

В вашем примере код был своего рода смесью между ними. Также value.sum содержит введенные числа, а не value.

Вот как это сделать правильно с помощью объекта функций обновления:

const calculator = createDecorator({
    field: /day\[\d\]\.sum/,
    updates: {
        total: (ignoredValue, allValues) => (allValues.day || []).reduce((sum, value) => sum + Number(value.sum || 0), 0)
    }
});

или обновления для нескольких полей (на самом деле только одно, но может быть и больше):

const calculator = createDecorator({
    field: /day\[\d\]\.sum/,
    updates: (ignoredValue, fieldName, allValues) => {
        const total = (allValues.day || []).reduce((sum, value) => sum + Number(value.sum || 0), 0);
        return { total };
    }
});

Кроме того, для справки приведены определения средства обновления Typescript:

export type UpdatesByName = {
  [FieldName: string]: (value: any, allValues?: Object, prevValues?: Object) => any
}

export type UpdatesForAll = (
  value: any,
  field: string,
  allValues?: Object,
  prevValues?: Object,
) => { [FieldName: string]: any }

export type Updates = UpdatesByName | UpdatesForAll
person Istvan Szasz    schedule 18.10.2019
comment
Большое спасибо за Ваш ответ! ???? Но я выбрал другой ответ, так как он указал на мою ошибку. Если бы я мог, я бы выбрал оба! - person jupiteror; 19.10.2019