T
TanStack3y ago
fascinating-indigo

Prevent loader from rerunning

Is there a way to prevent a loader from rerunning when certain conditions are met, similar to something like this from Remix (https://remix.run/docs/en/v1/api/conventions#unstable_shouldreload) ? I have several search parameters that change often and I want to prevent the loader from running every time one of these parameters change.
6 Replies
absent-sapphire
absent-sapphire3y ago
How would you like to customize that behavior? And would you like it to be optimized for an opt-out or an opt-in?
fascinating-indigo
fascinating-indigoOP3y ago
I'd have to think more about this conceptually. I think it makes sense that loaders by default always re-run and you would have to explicitly define when they don't run, with the exception of route change which you can't prevent. Kind of an example was this route I was working with where I only want to load appointments for a calendar when the start and end dates change, but not when the selected date changes. Since I'm storing all the data in the search params, including which date the user selects, the loader re-runs every time a new date is selected.
const appointmentsRoute = rootRoute.createRoute({
path: "appointments",
component: Appointments,
validateSearch: z.object({
startDate: z.string(),
endDate: z.string(),
selectedDate: z.string(),
}),
shouldReload: ({ url, prevUrl }) => {
if (url.search.selectedDate !== prevUrl.search.selectedDate) {
return false;
}
},
loader: async ({
search: { startDate, endDate, selectedDate },
}) => {
const appointments = await getAppointments({
startDate: startDate,
endDate: endDate,
});
return appointments;
},
});
const appointmentsRoute = rootRoute.createRoute({
path: "appointments",
component: Appointments,
validateSearch: z.object({
startDate: z.string(),
endDate: z.string(),
selectedDate: z.string(),
}),
shouldReload: ({ url, prevUrl }) => {
if (url.search.selectedDate !== prevUrl.search.selectedDate) {
return false;
}
},
loader: async ({
search: { startDate, endDate, selectedDate },
}) => {
const appointments = await getAppointments({
startDate: startDate,
endDate: endDate,
});
return appointments;
},
});
So maybe having some way to access the current and previous URLs and being able to prevent a reload by returning false and preventing the reload. I don't know if any of that makes sense, I'm not super technical, so this may not be feasible at all.
absent-sapphire
absent-sapphire3y ago
So the solution going forward looks like this:
absent-sapphire
absent-sapphire3y ago
GitHub
router/main.tsx at beta · TanStack/router
🤖 Type-safe router w/ built-in caching & URL state management for JS/TS, React, Preact, Solid, Vue, Svelte and Angular - router/main.tsx at beta · TanStack/router
absent-sapphire
absent-sapphire3y ago
That protects loaders and routes from both navigation AND prefetching/fetching
fascinating-indigo
fascinating-indigoOP3y ago
Awesome, this looks great. Thank you!

Did you find this page helpful?