bounty将在5天后过期。回答此问题可获得+150的声誉奖励。Leff正在寻找来自声誉良好的来源的答案。
我有一个父组件,在其中使用React Query执行API获取:
export default () => {
const { caseId } = useCaseProvider();
const { api } = useMockApi();
const { data: caseData, refetch, isRefetching } = api.getCasaData(caseId);
const mutation = api.postCaseData(caseId);
return (
<Suspense fallback={<Loader size="3xlarge" title="loading..." />}>
<CaseForm
caseData={caseData}
refetch={refetch}
isRefetching={isRefetching}
mutation={mutation}
/>
</Suspense>
);
};
在CaseForm组件中,由于保存和提交都有按钮,所以我需要根据单击的是哪一个来设置它们的加载状态。为此,我考虑使用useState
钩子设置标志:
const CaseForm = ({ caseData, refetch, isRefetching, mutation }) => {
const { caseFormValues, setCaseFormValues, setActiveStep } = useCaseProvider();
const initialValues = caseFormValues ?? createInitialValues(caseData);
const [isSaving, setIsSaving] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const onSave = async () => {
setIsSaving(true);
await save();
setIsSaving(false);
};
const save = async () => {
await mutation.mutate({ ...caseData, ...getValues() });
setCaseFormValues(getValues());
};
const onSubmit = async () => {
setIsSubmitting(true);
await save();
setIsSubmitting(false);
setActiveStep(STEPS[Stepper.INCOME]);
};
但是,当我点击这些按钮中的任何一个时,isSubmitting和isSaving总是保持false
。我在这里做错了什么,我该如何解决这个问题?
2条答案
按热度按时间owfi6suc1#
主要的问题是你的
save()
函数是async
,但是你没有await
它,结果是在onSave()
期间的序列会马上把isSaving
的值设置回false。由于在下一次渲染中没有变化(
isSaving
已从false
-〉true
-〉false
发生变化),因此在isSaving
值上没有观察到变化。修复方法是
save()
save()
函数,或重置await
之后的变量。可能的修复
或者
甚至
同样的逻辑也适用于
onSubmit()
。llycmphe2#
您正在使用
mutation.mutate
沿着await
,但这不是一个异步函数。您应该使用可以等待的mutation.mutateAsync
,这是两个不同的函数,只有mutateAsync
返回Promise。当像这样使用时,
setIsSaving(true)
和setIsSaving(false)
会被快速连续调用,或者作为一个微任务,或者作为下一个tick(不检查就不确定),你看不到它们之间的渲染结果。旁注:
突变本身有
mutation.isLoading
,所以最终的问题是为什么要自己复制它。