-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
4.0 Preview Use Cases #3846
Comments
For data loading, the key isn't going to actually be managing loading of data. It's more in the static analysis of routes so you can determine what components are loaded (or need to be loaded) and ask them what data they will need (as static props). This comes from the loss of a top level route config being the core construct. I know @threepointone is working on something like this, and I'm also thinking about it (haven't had time yet...). While I don't intend to answer the data loading part, I at least want to give a place you can go ask and get the info you need to schedule your fetches appropriately. |
Yeah, ultimately these are all use cases that are handicapped by the same thing, which is the loss of top-down routing. |
cc @taion who maintains the relay integrations as well |
I'm just barely diving into the v4 changes, so take this with a grain of salt, but what about doing a 2-pass render to handle this data batching. This would ideally be abstracted into a module, but something like:
This could be tweaked to work server-side and client-side. For route config, I believe the current docs site already has an example of how you might abstract your route config into an object and then dynamically render the tree. I will say that I'm generally on board with react-router having a much smaller API size and then support modules being built around it to handle various specific use-cases. |
@cpsubrian Unfortunately, 2 passes might not be enough. Think about the URL |
@timdorr Fair enough that it can get tricky. I'd probably have my 'loader api' required the components to abstractly return their data requirements (sorta like graphql) and then the root 'loader' would know how to weave together the various async requests to produce the desired result. That ends up being very app-specific and hard to put in a beginner-friendly example or module. |
My current loading API (redux-based) can handle cascading loader promises, but it works because you can dive into the router components tree and collect all the statically defined loaders. With the new API you'd actually need to render the tree and collect it up in componentWillMount instead. The missing piece, as you pointed out, is what if you need actual loaded data in order to complete the render. In my case I'd try to rely only on params from the location but that's not always possible. |
Named RoutesIf you don't define your routes up front then you can't suppport named routes. There seems to be a consensus among the React Router maintainers that named routes aren't helpful. I can only guess that they've never seen what named routes can do when implemented properly. Named routes are the only way to, for example, build reusable routing components like Pagers and Sorters |
As @ryanflorence said earlier today, nothing in v4 prevents you from defining your own static route config and using
It's also extremely important to consider that your data loading requirements are almost certainly not the same as anyone else's. So for us to prescribe an up-front data-loading strategy for everyone to use would be presumptuous. Truth is, there are many, many different strategies and needs when it comes to data loading, and we are more interested in routing here. Having said that, I do anticipate that we will eventually have some solutions for loading data. But when we do, they will not be part of the core of react-router. They will almost certainly build on top of react-router, but they won't replace it. |
(Thanks @grahammendick for mentioning Named Routes, which is something I missed, and is something I find very useful coming from a Django background) Having to define URL-based logic twice (i.e. the static behaviour in addition to RR's API) doesn't strike me as being much of a solution. The fact that it appears to be necessary in order to use React Router and support the use cases mentioned in this issue seems to be a legitimate argument against using RR4. Now this doesn't mean you absolutely shouldn't use it, just that you need to be aware that the new API is going to create more work for you if you need to do anything similar to these use cases. The way i'm reading the situation, is that we're leaning towards the 2nd outcome I anticipated: Namely that if you have a heavy need to support these use cases, React Router probably shouldn't be your first choice when it comes to selecting a routing solution. To that end, i'd truly appreciate the limitations being properly documented and made visible in the readme. I've gone on about this repeatedly in the past, but reducing the duration between a user discovering a library and working out whether it's going fulfill their requirements is the single most important problem that a project's documentation has to solve. Showing off your slick API is super important too, but is ultimately wasted time if the project is unsuitable. |
This isn't to say that the RRv4 API isn't a lot cleaner in many ways, but I don't think it's correct to represent RRv4 as offering anything to users who were leaning on routing for data fetching with the RRv2 API. The RRv4 API doesn't preclude implementing the RRv2 API on top of it, but it also doesn't really offer anything particularly useful in doing so – I have no reason to use Again, that's not a problem – it's just not a one-size-fits-all solution. |
@AndrewIngram Why do we have to advertise all the use cases that we don't handle in our README? We don't tell people we're good for data loading. We never have. React itself doesn't handle data loading. Does it say "React, NOT for data loading"? Of course not. |
The way I see it is React Router becomes a smaller thing so that can get out of the way of itself. Meaning, other libraries can use it more freely as a building block to whatever version of routing, data loading, application architecture, etc. that they want to define. Much like Redux doesn't define any architecture to your application's handling of state (only the mechanics of how it's handled), Router shouldn't define anything about how your application should be built. I think what's available here is a huge opportunity to come in and define what is essentially the "Rails" or "Django" of the React ecosystem. Nothing like that has really taken off yet. But now that Router is less opinionated by design, there is room to apply your own opinions and build a framework of that scale. Keep in mind this is a prerelease version. This is to give time for the ecosystem to adapt, patterns to develop, libraries to be written, blogs to be posted, screens to be cast, talks to be talked, etc. etc. Now is a great time to start experimenting with these kinds of ideas. We likely need another layer on top of Router to do page-level routing and static route analysis. And there are a number of ways to do that, so the experimenting starts now! 😄 |
Certainly, and nobody has had anything but good things to say about how clean the new API is. Where it's unhelpful is claiming that the exported It doesn't – and that's okay, not every library has to handle everything – but I think the claim that RRv4 offers useful primitives for building a route-based routing system requires better justification than pointing at 50 lines of code that wrap |
@taion I'm at a workshop today, but I'll write something this weekend/early next week so you can see what I'm talking about. Or, you could dig in and try and write something yourself if you don't wanna wait around for me to do it 😄 |
@mjackson firstly, because URLs are the API for the web, and many people will be coming from a background of expecting to be able to map a URL to a set of data dependencies. Secondly, because whilst the solutions were messy, previous versions of the API nonetheless did have solutions to these problems. Finally, so people stop asking you to support it and can get on with either finding or inventing other solutions. However, I feel like i'm just answering a rhetorical question... Sure the reasons to clearly document the limits of the scope of a project are obvious enough? |
People keep talking about Relay users. Relay 2 will know what data to load before JavaScript even downloads (they're using static analysis on your code before shipping it). So ... that means we don't even exist yet. How are we supposed to do anything? |
I'm waiting for Relay 3 where it knows what data to download before you even start writing your code. |
@timdorr Haha, if only you were joking. I await my 2nd career as chef after our new artificial intelligence overlords take over the programming industry 😄 |
Re-opening so people can continue this discussion if they wish. |
Please see library for fetch data with React-Router v4 https://github.com/MrCheater/react-router-fetch-data (MIT) |
@MrCheater thank you! Has similar idea yesterday but also with nested matches (mostly for old code migration) |
My current recommendation is to not build on top of RRv4 if you're using Relay. The requirements around static data fetching mean that, in the Relay use case, the RRv2 architecture is a better match to what you're looking for – there's no real value-add from component-based |
Thanks @MrCheater for sharing his route-based solution. I am use to checking if the data exists (maybe it doesn't yet due to server-side timeout or a client-side request) in the container, does the route-based method also handle this? Has anyone else managed to come up with a component-based solution? It is the component or container that usually does the data fetching, so it feels like a good idea to carry on with this method. or am I being a bit 'closed-minded' to other options? |
@peter-mouland |
What do you guys think about these libraries for async loading: https://github.com/ericclemmons/react-resolver Also if these don't work out, there is also a ui-router port for react which was the defacto solution for angular apps: |
@AndrewIngram Did you find a solution for implementing Sitemaps? @timdorr If I want to have a sitemap tree view with all my routes is this possible / is there a suggested approach? Have any patterns emerged in the community? |
The background for this issue is that there are use cases fundamental to real world projects (public websites more so than apps behind an auth check), that I believe aren't supported by the upcoming version 4 of React Router.
These use cases aren't exhaustive, but will hopefully get a productive conversation started. Anyone should feel free to add more to the list. I think there are two possible desirable outcomes here:
Use cases
1. Data-loading
This is the most obvious one, so a good one to start with. Previously, when we used routes, it was possible to map a URL to a list of entry point components. If components were able to statically define their data requirements (a fetch operation for some, a GraphQL fragment for Relay users), it was possible to fetch all the data before rendering the components.
The new API defines matching behaviour in the render method of the components, which means a child "route" can't start loading its data until the parent's render method has been called. Ultimately this means the render process will be staggered and data requests turned into a sequential waterfall. Avoiding this request waterfall is critical to performance.
In previous versions, it was possible for Relay users to fire off all data requests in parallel, or even batch everything up into a single request. This was only possible thanks to being able to statically work out all the data dependencies up front.
Note: I'm not ignoring the value of being able to defer some data dependencies and showing loading messages instead, but I think we'd be going down a tangent if we dwelled on it.
2. Sitemaps, robots and apple-app-site-association files
This is a bundling of a few different requirements that are all basically the same.
Basically, this use case is about the need to have hosted files that explain the structure of the site. At small scales these files can be hard-coded. At larger scales it needs to be possible to generate them (and generate them efficiently). With top-down route definitions, this is relatively easy.
The text was updated successfully, but these errors were encountered: