尽管有条件渲染,React 表单可以提交两次

React form can be submitted twice despite conditional render

我有一个与 Redux 耦合的 React 应用程序。有一个组件呈现表单包装器(Formik 的自定义实现),而表单输入本身由子组件呈现。

(不是确切的代码,但明白了要点。)

...
render() {
  const {
    config,
    updateContactDetails,
    errorMessages,
    contactDetails,
    previousFormValues,
    isUpdating,
  } = this.props;
  const { apiBaseUrl, fetchTimeout, globalId } = config;
  const initialValues = previousFormValues || getInitialContactDetailsValues(contactDetails);

  if (isUpdating) return <Spinner />;
  return (
      <Form
        initialValues={initialValues}
        validate={(values) => validate(values, errorMessages)}
        onSubmit={(values) => {
          updateContactDetails(apiBaseUrl, globalId, values, fetchTimeout); // dispatch action
        }}
      >
        <ContactDetailsForm content={content} />
      </Form>
  );
}
...

当你点击ContactDetailsForm中的提交按钮时,Redux store中isUpdating的值被设置为true。正如您在上面看到的,这导致表单被一个微调器组件替换。但是,以某种方式可以通过单击按钮两次来提交表单两次。 怎么会这样?在用微调器替换表单之前是否会重新渲染?我知道我可以通过将 isUpdating 传递给 ContactDetailsForm 并使用它来禁用按钮来解决问题,但我仍然想阐明原因。

编辑

reducer 看起来像这样,以防有帮助:

case UPDATE_CONTACT_DETAILS_START: {
  return {
    ...state,
    errorUpdatingContactMethods: {},
    hasUpdatedContactDetails: false,
    isUpdating: true,
    contactDetailsValues: action.values,
  };
}

您应该根据 isUpdating 属性在按钮上设置 disabled 属性。这可能只是一个竞争条件。