英文:
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
true
if the query is in a "hard" loading state. This means there is no cached data and the query is currently fetching (isLoading = true
only at the 1st query when component is mounted). -
isFetching
:Is
true
whenever 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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论