You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We all know one of the core concepts of remix is the fact that we have parallel routing (loaders). Which is great in many situations and it makes you restructure your data flow efficiently in most cases. But however, sometimes we do have scenarios in which we need something to be loading sequentially, which is not possible and causes dirty workarounds or even more complex code (including duplicate code and unnecessary requests).
It is a quite common, to have a layout route or even an index route to resolve some data, which needs to be reused down the line. Currently there is no way to pass along data down the line using loaders. Although I can imagine this should not be a "standard" way of using Remix, I do really think having the possibility (aka flexibility) to do this, would help lots of developers using Remix.
Of course you can pass data down the line within your "Component", using React Context api or provide context to your Outlet. But this is something different. It could be the case that you need to have some data available in your loader, to determine what you should do next (redirect/request). Authorization is in my opinion one of the most common scenarios, you dont want to trigger some auth request on each loader down the line, this causes unnecessary load and to much logic (even duplicate code) scattered across different loaders.
I took a deep dive in the source code, to see how the loaders are being resolved (in parallel) and tried to come up with a straight forward implementation to "enable" sequential loading of routes, without losing the parallel aspect. For example if you have a structure like this (https://your-app.dev/lorem/ipsum/foo/bar):
You can easily group the sequential routes (loaders) and split up the matchesToLoad so that you first resolve all loaders up until the sequential loaders (in parallel). After that resolve the "sequential" loaders sequentially. And finally resolve the remaining loaders in parallel again. Concat the results all together and everything will still work perfectly fine. Giving us the capability of deciding IF we want to load a part of the route sequentially, with proper reasoning and thinking about performance.
The nice thing about this is, the moment you specify that you want to load a specific route/loader sequentially you can pass down the result from that loader down the line (using the requestContext, which will be available in the loader args as context). The ID from the route is unique which can be added as identifier and you can reuse your data from parent (sequential) loaders in your child loaders (which can be either parallel or again sequential).
I have a working example with minimal code changes and would love to see this being implemented or at least considered, I think this would be a great feature that improved the flexibility of using remix.
Some implementation details:
// routes/_app/lorem/index.tsx// (https://remix.run/docs/en/main/route/handle)// Define a Handle with the property "sequential" to be true// so that if you dont, parallel loading (as it suppose to be) will be always the default.exportconsthandle={sequential: true,};exportconstloader: LoaderFunction=async(props: LoaderArgs)=>{constheaders={'content-type': 'application/json; charset=utf-8'};returnjson({auth: true},{ headers });}// ------------------------------// routes/_app/lorem/ipsum/route.tsx// Inside your (child) loaders you will have access to the response being returned from // all of your (sequential) parent routes that are already resolvedexportconstloader: LoaderFunction=async(props: LoaderArgs)=>{constparent=props.context["routes/_app/lorem/index"];// {// type: 'data',// data: { auth: true },// statusCode: 200,// headers: { 'content-type': 'application/json; charset=utf-8' }// }returnjson({});};
If anyone would like to have a working example, I would love to provide some implementation details. It requires a little bit of code but no more than +/- 30 lines, depending on how explicit we want to write our code 😄 (and most important no major breaking changes at all, as far as I could tell. But of course it would be best to have some Remix expert take a look at it).
I can make a PR with the initial changes, but after I read the docs on contributing it said it was better to create a proposal for new features instead of just making a PR 🔥💻
PS: There is a similar discussion/proposal on this topic #8729, but to me it feels a bit too much as I would like to have a clean/simple out of the box implementation using that what Remix already has built in
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
We all know one of the core concepts of remix is the fact that we have parallel routing (loaders). Which is great in many situations and it makes you restructure your data flow efficiently in most cases. But however, sometimes we do have scenarios in which we need something to be loading sequentially, which is not possible and causes dirty workarounds or even more complex code (including duplicate code and unnecessary requests).
It is a quite common, to have a layout route or even an index route to resolve some data, which needs to be reused down the line. Currently there is no way to pass along data down the line using loaders. Although I can imagine this should not be a "standard" way of using Remix, I do really think having the possibility (aka flexibility) to do this, would help lots of developers using Remix.
Of course you can pass data down the line within your "Component", using React Context api or provide context to your Outlet. But this is something different. It could be the case that you need to have some data available in your loader, to determine what you should do next (redirect/request). Authorization is in my opinion one of the most common scenarios, you dont want to trigger some auth request on each loader down the line, this causes unnecessary load and to much logic (even duplicate code) scattered across different loaders.
I took a deep dive in the source code, to see how the loaders are being resolved (in parallel) and tried to come up with a straight forward implementation to "enable" sequential loading of routes, without losing the parallel aspect. For example if you have a structure like this (https://your-app.dev/lorem/ipsum/foo/bar):
You can easily group the sequential routes (loaders) and split up the matchesToLoad so that you first resolve all loaders up until the sequential loaders (in parallel). After that resolve the "sequential" loaders sequentially. And finally resolve the remaining loaders in parallel again. Concat the results all together and everything will still work perfectly fine. Giving us the capability of deciding IF we want to load a part of the route sequentially, with proper reasoning and thinking about performance.
The nice thing about this is, the moment you specify that you want to load a specific route/loader sequentially you can pass down the result from that loader down the line (using the requestContext, which will be available in the loader args as context). The ID from the route is unique which can be added as identifier and you can reuse your data from parent (sequential) loaders in your child loaders (which can be either parallel or again sequential).
I have a working example with minimal code changes and would love to see this being implemented or at least considered, I think this would be a great feature that improved the flexibility of using remix.
Some implementation details:
If anyone would like to have a working example, I would love to provide some implementation details. It requires a little bit of code but no more than +/- 30 lines, depending on how explicit we want to write our code 😄 (and most important no major breaking changes at all, as far as I could tell. But of course it would be best to have some Remix expert take a look at it).
I can make a PR with the initial changes, but after I read the docs on contributing it said it was better to create a proposal for new features instead of just making a PR 🔥💻
PS: There is a similar discussion/proposal on this topic #8729, but to me it feels a bit too much as I would like to have a clean/simple out of the box implementation using that what Remix already has built in
Beta Was this translation helpful? Give feedback.
All reactions