英文:
React-query - how to check when refetching has been finished
问题
我有一个组件,在该组件中,我使用react-query来获取数据并设置初始表单值:
const { data: caseData, refetch, isRefetching } = useQuery({
queryKey: `caseData-${caseId}`,
queryFn: () => fetchCaseById(caseId),
staleTime: Infinity,
});
if (!caseData) return "Loading";
<CaseForm initialValues={createInitialValues(caseData)} refetch={refetch}/>
在CaseForm组件中,我有一个按钮,当单击时触发refetch函数:
<Button
type="button"
loading={isRefetching}
variant="secondary"
onClick={() => refetch()}
className="w-max"
size="small"
>
Reload
</Button>
我想在数据首次获取后以及后续的refetch后,仅创建初始值一次。我考虑将表单值提升到上下文提供程序中,以便在那里检查状态。类似以下方式:
const { data: caseData, refetch, isRefetching } = api.getCaseData(caseId);
<Suspense fallback="Loading">
<CaseForm initialValues={caseData} refetch={refetch}/>
</Suspense>
然后在CaseForm中:
const { caseFormValues, setCaseFormValues } = useCaseProvider();
useEffect(() => {
if (!caseFormValues) setCaseFormValues(initialValues);
}, []);
const {
handleSubmit,
control,
formState: { errors },
} = useForm({
defaultValues: caseFormValues ? caseFormValues : initialValues,
});
这可以帮助我在首次获取数据时设置初始值,但如何在数据完成重新获取后检查数据是否已重新获取,以便更新表单值呢?我无法使用isRefetching,因为它只在数据开始重新获取时显示。不确定如何检查这一点。
英文:
I have a component where I am fetching data with react-query and setting initial form values:
const { data: caseData, refetch, isRefetching } = useQuery({
queryKey: `caseData-${caseId}`,
queryFn: () => fetchCaseById(caseId),
staleTime: Infinity,
});
if (!caseData) return "Loading"
<CaseForm initialValues={createInitialValues(caseData)} refetch={refetch}/>
Inside a CaseForm component I have a button that onClick triggers refetch function:
<Button
type="button"
loading={isRefetching}
variant="secondary"
onClick={() => refetch()}
className="w-max"
size="small"
>
Reload
</Button>
I would like to only create initial values once after data is fetched first time on mount and later on refetch. I thought of lifting form values into context provider so that i can check state there. Something like this:
const { data: caseData, refetch, isRefetching } = api.getCaseData(caseId);
<Suspense fallback="Loading">
<CaseForm initialValues={caseData} refetch={refetch}/>
</Suspense>
And then in CaseForm:
const { caseFormValues, setCaseFormValues } = useCaseProvider();
useEffect(() => {
if (!caseFormValues) setCaseFormValues(initialValues);
}, []);
const {
handleSubmit,
control,
formState: { errors },
} = useForm({
defaultValues: caseFormValues ? caseFormValues : initialValues,
});
That can help me with initial values when data is being fetched for the first time, but how can I check if data has been refetched, once it is finished being refetched so that I can updated form values?
I can't use isRefetching since that only shows when data has started refetching. Not sure how can I check this?
答案1
得分: 1
Sure, here is the translation of the code-related part:
// Callback of the refetching
const handleRefetch = () => {
refetch().then(res => {
setCaseFormValues(res?.data) // updated data here
// do whatever you want here...
})
}
<Button
type="button"
loading={isRefetching}
variant="secondary"
onClick={handleRefetch}
className="w-max"
size="small"
>
Reload
</Button>
If you need further translation or have other code-related questions, please feel free to ask.
英文:
UPDATED ANSWER:
> I want to know when data has arrived after refetch, and only in case of a refetch.
Well, the refetch() function returns a promise, so just do what you want after it completed. So inside that promise, you don't need to check condition whether this is a initial loading or the refetching.
// Callback of the refetching
const handleRefetch = () => {
refetch().then(res => {
setCaseFormValues(res?.data) // updated data here
// do whatever you want here...
})
}
<Button
type="button"
loading={isRefetching}
variant="secondary"
onClick={handleRefetch}
className="w-max"
size="small"
>
Reload
</Button>
INITIAL ANSWER:
You don't need to handle this yourself. react-query provides an option enabled.
enabled is true by default, which means the query is triggered automatically by react-query. You can set enabled: false to disable this automation, so that it will only run 1st time on mounting, then it only runs to get new data on the time you call refetch().
One more thing, react-query has 3 different variables to tracking the fetching states, which are:
-
isLoading:Is
trueif the query is in a "hard" loading state. This means there is no cached data and the query is currently fetching (isLoading = trueonly at the 1st query when component is mounted). -
isFetching:Is
truewhenever a request is in-flight, which includes initial loading as well as background refetches.Will be true if the query is currently fetching, including background fetching.
-
isRefetching:Is true whenever a background refetch is in-flight, which does not include initial loading.
Is the same as
isFetching && !isLoading.
You can find more from the docs.
Hope this can help!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论