仅发送在 formik onSubmit 中更改的值
Only send values that have changed in formik onSubmit
我有一小部分 table 数据,由页面加载时的 api 调用预先填充。 table 中的每一行都有一个设施名称和一个来自 api 调用的 Enabled
值。如果 Enabled
== true 复选框显示为已选中。
我有几个变灰的复选框,因为根本无法更改,所以该字段上有一个 readOnly 属性。
关于我的问题,为简洁起见,我压缩了 table 中显示的设施列表,但实际上可能有 X
数量的设施。在我的 onSubmit
函数中,我只想发送设施名称和 enabled
值(如果它们是 selected/deselected 而不是每次按下提交时都发送整个列表。
理想情况下,我希望发送的数据的形状如下所示:
{
facilityName: "Backup Restore",
enabled: true
}
现在,我已经能够仅隔离 facilityName
和 enabled
值,但我无法确定仅包含表单中已更改的值。就像我上面说的,不是每个设施名称和启用的 key/value 都应该在每次按下提交时只发送已更改的那些。
这是我目前在我的 onSubmit 函数中拥有的(并且可以在下面的沙箱中看到)
<Formik
enableReinitialize
initialValues={{
facilities: loggingFacilities
}}
onSubmit={async (values, { setSubmitting }) => {
alert(JSON.stringify(values, null, 2));
try {
setLoggingFacilities(values.facilities);
const valuesToSend = values.facilities.map(facility => {
return {
key: facility.facilityName,
value: facility.enabled
};
});
.....
我有一个codesandbox here
从你的 onSubmit
回调的第二个参数,你可以访问 props
,所以你可以将 values
与 props.initialValues
进行比较,或者你已经调用了你的道具用于初始化表单。
实际上,那是 suggestion from Jared Palmer:
You can compare initialValues
and values within handleSubmit
/ onSubmit
.
使用 Array.prototype.filter()
看起来像这样:
onSubmit={async (values, { props, setSubmitting }) => {
// Let's assume this has the same format as `values.facilities`:
const { initialValues } = props;
try {
setLoggingFacilities(values.facilities);
const valuesToSend = values.facilities.filter((facility, i) => {
// Let's send only those that have just been disabled or enabled:
return facility.enabled !== initialValues[i].enabled;
}).map((facility) => ({
key: facility.facilityName,
value: facility.enabled
}));
// ...
} catch(err) { ... }
}
试试这个:
const getChangedValues = (values, initialValues) => {
return Object
.entries(values)
.reduce((acc, [key, value]) => {
const hasChanged = initialValues[key] !== value
if (hasChanged) {
acc[key] = value
}
return acc
}, {})
}
我稍后会到达这个问题,但我认为你可以使用 dirty 标志。它似乎为您做了与初始值的深入比较。并将与@Dazinger 方法很好地互补。
dirty: boolean
Returns true if values are not deeply equal from initial values, false otherwise. dirty is a readonly computed property and should not be mutated directly.
我有一小部分 table 数据,由页面加载时的 api 调用预先填充。 table 中的每一行都有一个设施名称和一个来自 api 调用的 Enabled
值。如果 Enabled
== true 复选框显示为已选中。
我有几个变灰的复选框,因为根本无法更改,所以该字段上有一个 readOnly 属性。
关于我的问题,为简洁起见,我压缩了 table 中显示的设施列表,但实际上可能有 X
数量的设施。在我的 onSubmit
函数中,我只想发送设施名称和 enabled
值(如果它们是 selected/deselected 而不是每次按下提交时都发送整个列表。
理想情况下,我希望发送的数据的形状如下所示:
{
facilityName: "Backup Restore",
enabled: true
}
现在,我已经能够仅隔离 facilityName
和 enabled
值,但我无法确定仅包含表单中已更改的值。就像我上面说的,不是每个设施名称和启用的 key/value 都应该在每次按下提交时只发送已更改的那些。
这是我目前在我的 onSubmit 函数中拥有的(并且可以在下面的沙箱中看到)
<Formik
enableReinitialize
initialValues={{
facilities: loggingFacilities
}}
onSubmit={async (values, { setSubmitting }) => {
alert(JSON.stringify(values, null, 2));
try {
setLoggingFacilities(values.facilities);
const valuesToSend = values.facilities.map(facility => {
return {
key: facility.facilityName,
value: facility.enabled
};
});
.....
我有一个codesandbox here
从你的 onSubmit
回调的第二个参数,你可以访问 props
,所以你可以将 values
与 props.initialValues
进行比较,或者你已经调用了你的道具用于初始化表单。
实际上,那是 suggestion from Jared Palmer:
You can compare
initialValues
and values withinhandleSubmit
/onSubmit
.
使用 Array.prototype.filter()
看起来像这样:
onSubmit={async (values, { props, setSubmitting }) => {
// Let's assume this has the same format as `values.facilities`:
const { initialValues } = props;
try {
setLoggingFacilities(values.facilities);
const valuesToSend = values.facilities.filter((facility, i) => {
// Let's send only those that have just been disabled or enabled:
return facility.enabled !== initialValues[i].enabled;
}).map((facility) => ({
key: facility.facilityName,
value: facility.enabled
}));
// ...
} catch(err) { ... }
}
试试这个:
const getChangedValues = (values, initialValues) => {
return Object
.entries(values)
.reduce((acc, [key, value]) => {
const hasChanged = initialValues[key] !== value
if (hasChanged) {
acc[key] = value
}
return acc
}, {})
}
我稍后会到达这个问题,但我认为你可以使用 dirty 标志。它似乎为您做了与初始值的深入比较。并将与@Dazinger 方法很好地互补。
dirty: boolean Returns true if values are not deeply equal from initial values, false otherwise. dirty is a readonly computed property and should not be mutated directly.