Add ability to control which loaders get called on transitions? #2390
Replies: 11 comments
-
Related to #175, maybe can hit both use-cases with this. |
Beta Was this translation helpful? Give feedback.
-
If there were some way to give the loader more information about the request (like the previous location and params and maybe even whether this is a client request) then we wouldn't need a special API for this. No API is better than an API. |
Beta Was this translation helpful? Give feedback.
-
@kentcdodds if you give the loader information then you called the loader. Remix already makes good decisions about when to a call or loader or not, but sometimes it calls it when the app developer knows it didn't need to. The point is to hook into that and say "it's all good, don't call this". |
Beta Was this translation helpful? Give feedback.
-
Right, but keep in mind it's not the loader we're trying to avoid calling. It's what the loader does that's the problem. If it could just have some logic within the loader to say "nevermind, I don't need to get new data, use the old stuff" then we've effectively moved what you were thinking should go into that This is all related to several other issues I just commented on. I think the loader could be more powerful at making these decisions (and potentially other decisions we don't realize we'll need support for) if it got more information in the loader. I'd put together a code example of I wasn't on my phone while my kids are falling asleep 😅 |
Beta Was this translation helpful? Give feedback.
-
Just making the HTTP request and awaiting the response isn't free and on slow connections would still cause UX issues, we can skip all of it with a check in the client (just like the remix data diffing already does). Also, now loaders have think about more than what data to load and we'd also need some weird special response that means "ignore my response, use what's in the client side route cache". |
Beta Was this translation helpful? Give feedback.
-
Oh right. I thought we were making an HTTP request either way 🤦♂️ So that |
Beta Was this translation helpful? Give feedback.
-
Only client code :) |
Beta Was this translation helpful? Give feedback.
-
🤦♂️🤦♂️ |
Beta Was this translation helpful? Give feedback.
-
I like the |
Beta Was this translation helpful? Give feedback.
-
About
Here's my proposal: export let searchKeys = ['title'];
export default function Route() {
// Only reload when "title" search change
let data = useLoaderData();
} I think of a loader refetch as an effect. Like React's React.useEffect(() => {
fetch(new URL({
pathname: compile(pathPattern, location.params),
search: location.search,
}));
}, [pathPattern, location.params, location.search]); But actually we want this React.useEffect(() => {
fetch(new URL({
pathname: compile(pathPattern, { ...locationRef.current.params, ...paramsThatThisRouteCares }, ),
search: searchThatThisRouteCares,
}));
}, [pathPattern, paramsThatThisRouteCares, searchThatThisRouteCares]); So Remix can ask developers for help to provide the accurate dependencies. // Tells Remix what search keys do we care
export let searchKeys = ['title', /^var-/];
export let params = ['region'];
export default function Route() {
// Only reload when "$region" param changes and "title" or /^var-/ search change
let data = useLoaderData();
} It looks boilerplate so we can have some defaults:
This covers most cases, at the cost of asking developers to explicitly declare what search keys do they need, which I think is acceptable. Further more, we can have something like eslint-plugin-react-hooks to help write dependencies: export let loader = ({ request, params }) => {
let url = new URL(request.url);
return fetch(`${API}/${params.region}?title=${url.searchParams.get("title")}`);
}
export let searchKeys = ['lang']; // error: unnecessary "lang", missing "title" Maybe we can bake it into Remix's builder to automatically add the exports. As for reload after form submission, it's more like invoking a callback, so I think #175 is a good direction. |
Beta Was this translation helpful? Give feedback.
-
If you've got a slow parent loader and then have a search/filter page below it, every change to the search params causes the parent loaders to re-render.
This is the right thing to do because search params span across loaders, so the safest thing is to call all of them.
But now you're paying a penalty to fetch that expensive thing in the parent every time your filter page changes.
This is silly, but kneejerk reaction:
Then the route can decide if it should update or not. This would only run on the client because document requests are stateless, no concept of "reload".
Something like that, I dunno.
Beta Was this translation helpful? Give feedback.
All reactions