Replies: 2 comments 2 replies
-
I agree. IMO loader is for the simple case: visit a route, fetch some async data, then use the data to render the route's component. I tried using it on a component that implements infinite scrolling, but I didn't see a way of passing a |
Beta Was this translation helpful? Give feedback.
-
This is a perfectly fine opinion! Personally, I prefer the more declarative approach of Links/Forms/loaders/actions and avoiding the need to do lots of conditional branching inside of components. I like when components can be "happy path" so I don't need the same However, that's not to say that it's everyones cup of tea - if you prefer the react query approach then by all means stick with it! But I would recommend at least trying loaders/actions out for a bit if you haven't, instead of just making a call based on the assumption that it's more verbose or complex. We've found in practice that it vastly simplifies your mental model by decreasing the complexity of your components (no more branching!) and also can result in material bundle size reductions since you don't need to do that conditional rendering and state-syncing all over the place. It's also worth noting that the author of react-query (Tanner) has since created Tanstack Router with support for data via route loaders, so there's evidence that even he thinks that the router should be aware of data dependencies.
A few thoughts on this:
So it can be as simple today as: const routes = [{
path: '/',
loader() {
return {
promise: fetchData(),
};
},
Component() {
let { promise } = useLoaderData();
return (
<React.Suspense fallback={<Loading />}>
<Await resolve={promise}>
{(value) => <p>The resolved value is {value}</p>}
</Await>
</React.Suspense>
);
},
ErrorBoundary() {
let error = useRouteError();
return <Error message={error.message} />
}
}] And eventually that (I think) will simplify down to: const routes = [{
path: '/',
loader() {
return {
promise: fetchData(),
};
},
Component() {
let { promise } = useLoaderData();
let value = use(promise);
return <p>The resolved value is {value}</p>
},
ErrorBoundary() {
let error = useRouteError();
return <Error message={error.message} />
}
}] |
Beta Was this translation helpful? Give feedback.
-
I just think this structure is simpler and clearer with react-query:
I just don't get the point of design of loader. I have to deal with defer response, wrap with <React.Suspense> and , and provide a function to retrieve async value. Or use nested child to instead of retrieve function but with useAsyncValue hooks...
It is so complex and a mess. I have to put 4-5 parts together to make it work: defer response, <React.Suspense>, <Await>, retrieve function, nested child, useAsyncValue...
It is more complex when I want to access context instances inside loader function, that ontext instances are generally provided by hooks from other libraries. Something like useQueryClient(), useTheme(), useConfig() ...
I don't understand the intention of this design. I just feel that kind of lazy data and state control should not be considered by the routing system. What were the considerations for these new features for react-router ?
Beta Was this translation helpful? Give feedback.
All reactions