Next.js Discord

Discord Forum

Component is not rerendered by react query

Answered
Sphecid wasp posted this in #help-forum
Open in Discord
Sphecid waspOP
I use react query to fetch data.
But component is not rerendered after data is fetched.
Dev tools for react query show this query as inactive, but with correct data inside.

Component is stuck in pending state until manual rerender.

This code prints only once, when data is still undefined. Log inside fetch function is not working too.

What happens here and how to fix it?

const {
    data: freeSlotsData,
    isPending,
    isError,
    error,
} = useQuery({
    queryKey: ['calendar', selectedDay.format('YYYY-MM-DD')],
    queryFn: fetchFunction,
    staleTime: 5 * 60 * 1000,
})

async function fetchFunction() {
    console.log('fetch data')
    const res = await fetch(
        `/api/get-available-day-time?date=${selectedDay.format('YYYY-MM-DD')}`,
    ).catch((error) => {
        console.error(error)
        return null
    })
    return ((await res?.json()) || null) as GetAvailableDayTimeResponse | null
}

console.log(
    'rerender',
    selectedDay.format('YYYY-MM-DD'),
    freeSlotsData,
    isPending,
    isError,
    error,
)
Answered by Luis
Do you have your queryFn defined inside the component?
Try moving it outside, because this is unnecessary being re-created on every render.
View full answer

9 Replies

Sphecid waspOP
I think I found when it stopped working.
I refactored component it is used in.
Previously it had early return and broke rules of hooks. So I split it into parent with early return and child. Query is running in child, after early return

But still no idea why exactly it is not working
Inactive query means that nothing uses it anymore. But component is still mounted.
Or even if component is unmounted somehow, it is still mounted again
Sphecid waspOP
I kind of worked around by putting query back into parent and passing it as prop to child
🤷
Do you have your queryFn defined inside the component?
Try moving it outside, because this is unnecessary being re-created on every render.
Answer
Also, pass the `selectedDay as an argument to your queryFn. It’s important that they’re both bounded so if the queryKey changes the queryFn re-triggers and synchronizes your state automatically.

const [selectedDate, setSelectedDate] = useState(…);

const date = selectedDate.format(“…”);

{
  queryKey:[‘calendar’, date]
  queryFn : async () => fetchFunction(date)
}
Sphecid waspOP
It works
:thinq: