如何将 react-final-from 计算字段与对象数组一起使用
How to use react-final-from calculated fields with an array of objects
我在 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
,但总数不会更新。我猜它不会从必要的字段中选择值。我该如何解决?这是我的 codesandbox https://codesandbox.io/s/react-final-form-calculated-fields-hkd65?fontsize=14.
您的代码片段中存在语法错误,尤其是计算器函数。此版本的函数有效:
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),
}
});
我做了两个主要的改变,
- 在reduce回调中,我把
Number(value || 0)
改成了Number(value.sum || 0)
- 我还将
updates
属性 设置为对象而不是函数。
Final-form-calculate 文档,假设更新程序可以是:
Either an object of updater functions or a function that generates
updates for multiple fields.
在您的示例中,代码是它们之间的某种混合。另外 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
我在 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
,但总数不会更新。我猜它不会从必要的字段中选择值。我该如何解决?这是我的 codesandbox https://codesandbox.io/s/react-final-form-calculated-fields-hkd65?fontsize=14.
您的代码片段中存在语法错误,尤其是计算器函数。此版本的函数有效:
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),
}
});
我做了两个主要的改变,
- 在reduce回调中,我把
Number(value || 0)
改成了Number(value.sum || 0)
- 我还将
updates
属性 设置为对象而不是函数。
Final-form-calculate 文档,假设更新程序可以是:
Either an object of updater functions or a function that generates updates for multiple fields.
在您的示例中,代码是它们之间的某种混合。另外 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