仅发送在 formik onSubmit 中已更改的值

IT技术 javascript reactjs formik
2021-05-05 16:39:05

我有一个小数据表,由页面加载时的 api 调用预先填充。表中的每一行都有一个设施名称和一个Enabled来自 api 调用值。如果Enabled== true 复选框显示为已选中。

我有几个复选框是灰色的,因为它根本无法更改,因此该字段上有一个 readOnly 属性。

关于我的问题,为简洁起见,我浓缩了表中显示的设施列表,但实际上可能有X很多设施。在我的onSubmit函数中,我只想发送设施名称和enabled值(如果它们已被选择/取消选择),而不是在每次按下提交时发送整个列表。

理想情况下,我希望发送的数据形状如下所示:

{
    facilityName: "Backup Restore",
    enabled: true
}

现在,我已经能够仅隔离facilityNameenabled值,但我无法弄清楚只包含表单中已更改的值。就像我上面说的那样,并不是每次按下提交时都应该发送每一个设施名称和启用的键/值,只是那些已更改的。

这是我目前在我的 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
                };
              });
              .....

这里有一个代码箱

2个回答

onSubmit回调的第二个参数中,您可以访问props,因此您可以与 diffvalues进行比较props.initialValues或者您已经调用了用于初始化表单的 prop。

实际上,这是Jared Palmer建议

您可以比较/ 中的initialValueshandleSubmitonSubmit

使用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
    }, {})
}