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,
});
<Suspense fallback="Loading">
<CaseForm initialValues={caseData} refetch={refetch}/>
</Suspense>
Inside a child 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 after data is fetched the 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(props.initialValues);
return () => {
setCaseFormValues(getValues());
};
}, []);
const {
handleSubmit,
control,
reset,
formState: { errors },
} = useForm({
defaultValues: caseFormValues ? caseFormValues : props.initialValues,
});
useEffect(() => {
if (!props.isRefetching) {
reset(props.initialValues);
}
}, [props.initialValues, props.isRefetching]);
This works fine when I fetch data for the first time, it also works fine when I click and refetch data. But, if the component is unmounted and then remounted again, so if I move to another page and go back to form again, useEffect
with dependencies props.initialValues, isRefetching
is being called, even though they haven't changed.
That resets the form values when I don't want that.
I have logged the values of the props and I can see that they are the same, yet useEffect
is called every time the component remounts. Why is that, what I am doing wrong here?
const { caseFormValues, setCaseFormValues } = useCaseProvider();
// dependencies log the same value
console.log('initialValues', props.initialValues)
console.log('isFetching', props.isFetching)
useEffect(() => {
if (!caseFormValues) setCaseFormValues(props.initialValues);
return () => {
setCaseFormValues(getValues());
};
}, []);
const {
handleSubmit,
control,
reset,
formState: { errors },
} = useForm({
defaultValues: caseFormValues ? caseFormValues : props.initialValues,
});
useEffect(() => {
console.log('called')
if (!props.isRefetching) {
reset(props.initialValues);
}
}, [props.initialValues, props.isRefetching]);