【问题标题】:React form can be submitted twice despite conditional render尽管有条件渲染,React 表单仍可以提交两次
【发布时间】:2019-09-27 14:35:40
【问题描述】:

我有一个与 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,
  };
}

【问题讨论】:

  • 您是否可以在重新渲染以显示 Spinner 之前单击该按钮两次?
  • formik 有 isSubmitting 属性
  • 我认为将isUpdating 传递给ContactDetailsForm 是行不通的。如果isUpdating 为真,ContactDetailsForm 甚至不应该渲染。可以分享一下onClick函数,redux action/reducer吗?这可能有助于阐明问题。
  • @EinarÓlafsson 是的,这就是谜。在我第二次单击按钮之前,您会认为表单会被微调器替换。 @Maria 以某种方式传递 isUpdating 确实有效,已经尝试过了。 ¯_(ツ)_/¯ 让我看看能不能贴一下reducer代码。
  • 您应该设置一个内部状态,一旦您单击按钮禁用它就会触发。听起来 Redux 的变化正在慢慢发生,以便及时重新渲染组件。

标签: javascript reactjs redux formik


【解决方案1】:

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

【讨论】:

  • 是的,我认为这可能是某个地方的竞争条件。您能否更深入地解释在这种情况下会如何发生?
  • @DavidMacKintosh 我不太确定,isUpdating 来自哪里?
  • 它在 Redux reducer 中设置,由单击提交按钮时发送的操作触发。来自 store 的值被映射到更高级别组件中的 prop,然后作为 prop 传递给上面的组件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 2019-05-26
  • 2017-04-15
相关资源
最近更新 更多