【发布时间】: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