-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Allow <Link to> to accept an object #2177
Comments
👍 in my humble opinion. As a matter of convenience, what about making location objects interchangeable with strings universally? That's tangentially related, so I can create another issue for discussion on the topic if you'd rather separate it out. |
That's an interesting idea. Feel free to open another issue where we can discuss further :) |
This looks really cool - it cleans up the API quite a bit. |
Just curious. What would happen when are using hash history and specify pathname and hash? Right now just doing a |
Should we close this in favor of #2186? I think that would supersede this issue. |
Yeah, we've got two issues on the same topic. Everyone move over to #2186! |
Since people seem to need it, and #1840 is closed and no further discussion is possible in there, and this is the first linked issue, and the discussion is spread over 10 or so different issues, I am posting this in here as well: https://github.com/adamziel/react-router-named-routes Sorry for the off-topic guys, it would be best if I was able to post it in the original issue; |
@adamziel you're free to create a new issue to discuss the possibility of reversible routes. A PR is best, since you can discuss a concrete change vs a theoretical. |
@timdorr as far as I understand a PR into the core would not be possible since named routes will only work as long as one does not use the async routes (which was mentioned by a guy in the other issue). A separate package on the other hand may provide it while deliberately breaking the fancy functionality. |
Indeed, we intended this to be supported in userland as a separate library (at least at first). |
I adjusted the code accordingly to your suggestion; If I issue a PR to include a link to that repo in UPGRADE_GUIDE.md would you merge it? |
I'm a bit ambivalent here. I like the idea of linking to a userspace named routes solution, but I'm a bit uncomfortable with giving the current solution an official imprimatur because it's somewhat incomplete. Thinking about this a little bit more, I think a correct solution would be something building off #2186 that presents as a history enhancer with the ability to both automatically set up names from sync route definitions and accepts some sort of mapping configuration for async routes. With #2186, this would then work for e.g. both What do you think? |
Sounds like a good idea, I'll take a look at this and maybe come up with something. |
Cool, thank you! #2186 is probably a little ways away because our main focus right now is shipping 1.0.0-final, but it offers a lot of cleanup possibilities, including this. |
I would have posted this sooner on #1840, but didn't expect version 1.0 to actually get released without named routes. React Router is an amazing library, and thanks for all your work on it, but removing such a fundamental feature with such weak justification throws its future for serious use into serious doubt. I'd imagine I'm far from the only one who doesn't intend to upgrade to any version of this library that doesn't include named routes without having to install an external library, and I can't imagine any valid reason it should have to involve a wrapper function like I apologize to whatever extent these things have already been said:
Is it possible to robustly support dynamic route loading and named routes at the same time? A few possibilities immediately come to mind:
How about an API something like this: let myRoute = {
getDynamicChildRoutes(location, cb) {
...
},
getChildRoutes(cb) {
...
}
}; Only one of The router recalculates all descendant routes of all routes that define It results in undefined behavior to return routes with the same name from multiple places in the route tree structure, even if there is no
Not only do URLs change before they're released, but not all web development occurs in a real-world niche where it's ideal to maintain redirects for every old URL.
|
That means we have a boolean mode switch at the top of our configuration, which basically results in two different libraries. The kind of things that need to be changed to support named routes are too systemic to simply flip on or off.
Loaded from where? This isn't a terrible idea or anything, but there's no clear mechanism for instructing
Doesn't work for large, code split apps or asynchronously-loaded routes. We are already running into this kind of thing as JSPM is gaining popularity. We can't assume we know the entirety of the route tree initially and have to run things async. This means we can't absolutely know the value of a named route ahead of time. As it's been pointed out before, the real solution to what everyone is looking for is a reversible routing solution. Building a bidirectional router is hard. Really hard. We may get there eventually, but for now it's best if we work on solutions externally and eventually merge in something that proves to hit all the right notes and be high quality. We're already doing this with scroll behavior and async properties. Reversible routes even have some initial solutions. I think we can come up with a few different options that solve different specific needs. |
I'm not a routing expert, I have no idea what bi-directional routing is, and I may not have a full understanding of a lot of the fundamental building blocks and current developments. I'm just trying to explain how I think you can implement the functionality that existed previously (named routes) and code splitting (which I also value extremely highly) at the same time for most use cases. I'm also saying that code splitting of routes in development does not imply code splitting of routes in production, and there's a good case to be made that the default use case decisions should be based on is bundling all routes in one file, which avoids the async performance issue for most cases as far as I can tell. There seem to be several different desired capabilities:
I guess what I was arguing is that 5 is not an issue if all routes are known on app load, routes can be known on app load without excessive wait times if they are bundled into the same file, (I believe) bundlers exist today that are capable of handling this organization, 2 is not an issue if all routes are bundled in the same file, and 3 and 4 are not important enough to remove 5 because supporting 5 would require extra complexity to support 3 and 4. Basically I'm just thinking of this as the minimal API for code splitting, seeing that it's easy to get all the routes for an app upfront (whether synchronously due to bundling in production, or asynchronously in development using a module loader that somehow supports asynchronous non-top-level requires - does that even exist? is it possible?), and wondering if there isn't some way to have named routes and code splitting while perhaps making the handling of dynamic routes and other asynchronous routes slightly more complex and/or require additional configuration. let route = {
component: () => require('component'),
childRoutes: [
() => require('route1'),
() => require('route2')
]
} |
In short: if you synchronously load child routes (or effectively synchronously), asynchronously load components, and bundle all routes into the same file for production, that allows code splitting and (easily implementable but also correct) named routes, is probably optimal for the vast majority of applications, and doesn't prevent doing any of the other things that have been done, but just might make them slightly more complicated. |
Necessary routes are loaded dynamically when making links. Sorry, if 'parentRouteName' is replaced with 'topLevelRouteName' it's probably clearer. Each link name would be an explicit full path to the desired route based on the names of its ancestor routes (all routes would require a name). If a path is partially unknown, each level route would be loaded in turn, then it's child routes, until the leaf route is loaded. I probably wouldn't advocate this over the solution above, but it would be easier. That probably also runs into issues with render() being synchronous. There could be workarounds for that though. |
This issue is really not the place to discuss named routes. We understand that many of our users want to have named routes, but at this point in time given the viability of implementing named route support outside of React Router core, we're looking much more at user-space solutions (and time permitting may release a preferred one of our own). @mjackson's summary in the OP of #1840 broadly covers the reasons why we don't think using route names is a preferred approach for front-end routing. At the same time, we're interested in providing support for use cases our users care about - there will be resolution here, but at this time it's most likely not going to take the form of |
I don't really care so much about specifically having a The first thing you need is
With this, you can push parameter values back into the path with a call like this:
So on thing you can do is define all your paths somewhere centrally as strings and then reference them, e.g.,
Or you can build create a
Bottom line is you don't actually need any special components, extra NPM modules, etc. to address the DRYness issue. That was sufficient for me. HTH |
I think that's a pretty good implementation of the pattern @mjackson proposes in the OP given the current API. That said, though, I think we can do better - one limitation is that what you have doesn't work particularly well for nested routes with nested path segments. Eventually I'd like to move toward pluggable transitions, such that you could do with a history extension e.g. import useNamedRoutes from 'use-named-routes'
const routes = <Route name="foo" path="/foos/:fooId" />
const history = useNamedRoutes(createBrowserHistory)({routes})
const router = <Router history={history} />
/* ... */
const link = <Link to={{name: 'foo', params: {fooId: 25}}}>Foo</Link> We're not there yet, though, and there's a lot of groundwork that needs to go into place before we can get there. |
Where is the appropriate place to discuss named routes, since the original issue was closed? I hope you don't mind if I summarize what I already said:
|
That's mostly correct, the same idea as on #2244 will allow explicitly mapping names to paths, if that's your cuppa. That said, the difficulty is really setting up the API such that we can nicely build named routes in a principled way as an extension at the lowest level possible. I think what I have above outlines a way forward. |
Hey guys, I locked this because it's really off base from the original issue. It's at best tangential, which results in us hiding valuable discussion in an issue that isn't apparent as to its contents. I would highly recommend opening a new issue with a specific proposal for change. Rather than just beating the "we want named routes" drum, a possible solution gives us something actionable to discuss. I would look to @jlongster's excellent issue (technically a PR) on Redux: reduxjs/redux#569 While it wasn't merged in, the discussion was fantastic and spawned some great external libraries for side effects in Redux. I would hope we can achieve the same thing here. Anyways, I won't re-lock, but hopefully we can move discussion to a more appropriate issue or PR. |
Sorry about that. The whole named routes thing is delicate enough that I don't want to give it more visibility. The stuff I've been thinking about in the context of routing in the RN context will have named routes fall out as a natural consequence (but as a history enhancer rather than part of RR core). I think @xogeny's post was relevant because it's essentially just an implementation of the pattern that is proposed in the OP, although we are getting a little sidetracked at this point. The basic summary is that
|
@gaearon suggests here that we could allow users to specify an object in their
<Link to>
. Then they could do something like:This would deprecate the
<Link query>
,<Link state>
, and (potential)<Link hash>
props and provide one place for people to put all their location-related data. It also makes it easy for people to see how they can wrap up "named routes" into a simple function:I personally like the idea. Just wanted to start some discussion here to see what others think.
The text was updated successfully, but these errors were encountered: