Skip to content
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

[DO NOT MERGE] Deprecate nested routes with absolute paths #3319

Closed

Conversation

taion
Copy link
Contributor

@taion taion commented Apr 14, 2016

From @ryanflorence on #3246 (comment):

Added the 3.0 milestone. We don't want to release this until we have features/improvements that depend on it, otherwise it's just annoying to our users. If we get those going we can move this to an earlier release.

@taion, mind enumerating the feature(s) that depend on this?

So I think at the end of it all, it looks like nothing strictly depends on this. It just makes a lot of things simpler, like relative link support, and lets us further optimize checking whether links are active.

So there's nothing strictly requiring this any more, but we should still do it sooner or later.

@taion taion changed the title Deprecate nested routes with absolute paths [DO NOT MERGE] Deprecate nested routes with absolute paths Apr 14, 2016
@ryanflorence
Copy link
Member

ryanflorence commented Apr 15, 2016

This is useful for making:

  1. our matching algorithm simpler
  2. route configs clearer to humans
  3. integrations that need to work with paths simpler (like named routes, relative routes, whatever else)

All previous UI + url combinations are still possible but with some route config finagling--that's really the only trade-off (and JSF*).

<Route path="inbox" component={Inbox}>
  <IndexRoute component={Dashboard}/>
  <Route path="/message/:id" component={Message}/>
</Route>

// becomes

<Route component={Inbox}>
  <Route path="inbox" component={Dashboard}/>
  <Route path="message/:id" component={Message}/>
</Route>

// or (could happen if other routes make it seem cleaner this way)

<Route path="inbox" component={Inbox}>
  <IndexRoute component={Dashboard}/>
</Route>
<Route component={Inbox}>
  <Route path="message/:id" component={Message}/>
</Route>

Worth it?

(*) JavaScript Fatigue

@bensmithett
Copy link

  1. route configs clearer to humans

I find the opposite true.

In this example, I have to manually concat 3 strings in my head to understand what the URL looks like

<Route path="/" component={App}>
  <Route path="about" component={About} />
  <Route path="inbox" component={Inbox}>
    <Route path="messages/:id" component={Message} />
  </Route>
</Route>

Whereas if you use absolute paths exclusively (we do) it's way clearer, especially in a sufficiently large route config.

<Route path="/" component={App}>
  <Route path="/about" component={About} />
  <Route path="/inbox" component={Inbox}>
    <Route path="/inbox/messages/:id" component={Message} />
  </Route>
</Route>

Mixing absolute & relative feels weird, but I'd miss being able to go exclusively absolute.

@timdorr
Copy link
Member

timdorr commented Apr 15, 2016

You can put a comment in there:

<Route path="/" component={App}>
  <Route path="about" component={About} />
  <Route path="inbox" component={Inbox}>
    <Route {/* path=/inbox/messages/:id */} path="messages/:id" component={Message} />
  </Route>
</Route>

That being said, it would be cool if there was some utility similar to rake routes in Rails to list out the full route tree.

@taion
Copy link
Contributor Author

taion commented Apr 15, 2016

@bensmithett I had thought about that use case a bit, and I'm not totally sure what to do there. The case we're worried about is less what you're doing, and more something like:

<Route path="/inbox" component={Inbox}>
  <Route path="/not-inbox" component={SomethingElse} />
</Route>

IMO this is quite confusing.

@bensmithett
Copy link

@taion is that necessarily a bad thing? I didn't think component nesting necessarily needed to dictate URL structure (via docs)

<Route path="/inbox" component={Inbox}>
  <Route path="/inbox/settings" component={InboxSettings} />
  <Route path="/message/:id" component={Message} />
</Route>

@timdorr yeeeah, but self-documenting code > comments!

(feel free to point me at other discussions, totally jumping in from the sidelines here 😄)

@timdorr
Copy link
Member

timdorr commented Apr 15, 2016

@bensmithett See #3172 for reference. I think the contributing team is all sold on this, so it's going to happen. Personally, I even think it's dangerous to support nested absolute routes, as it's more likely to lead to error-prone behavior, pain, and sadness for all involved.

@ryanflorence
Copy link
Member

ryanflorence commented Apr 15, 2016

I'm not against them, I <3 that the urls and component nesting are not coupled, that was a big deal to me when I first wrote any of the router code. But, I'm okay to see them go too since you can still accomplish the same UI + url combos w/o them.

Regarding the "all of them are absolute", I've seen quite a few people who prefer to do it this way ... wonder what it would look like if we allowed absolute urls as long as they matched their parent perfectly.

My main concern with this PR is that the benefits aren't huge anymore (we thought some other stuff depended on this, but turns out it doesn't), and to the folks using absolute paths, us removing them is just irritating.

@bensmithett
Copy link

bensmithett commented Apr 15, 2016

Though I'd be slightly :sadface: (it's a feature I like & get value from, haven't experienced any pain) if this PR shipped I'd survive. Trade-offs gonna trade-off 😄.

(Also ❤️ 🎁 🍺 core team for all your work!)

@ryanflorence
Copy link
Member

@bensmithett mind cut/pasting that question into a new issue since it's not related, I can answer it over there.

@bensmithett
Copy link

@ryanflorence done #3320

@taion
Copy link
Contributor Author

taion commented Apr 15, 2016

This PR is pending an update to not drop support for #3319 (comment).

There's one other benefit to dropping nested absolute &c. support – it's that we can make <Link> (isActive) faster. Without nested routes w/absolute paths that don't match their parents, pathname being a prefix of currentPathname becomes a necessary condition for a path to be active.

In other words, if we take out this feature, and we want to see if whether /foo is active, we can immediately say no whenever the current pathname doesn't start with /foo/ (and is not /foo). In cases where there are lots of links, likely most of them will fail the isActive check immediately on this prefix thing, which should speed things up quite a bit.

@ryanflorence
Copy link
Member

ryanflorence commented Apr 16, 2016

So sounds like here's where we're at:

  1. Stuff can get faster
  2. Implementation can be simpler
  3. Sync and Async route configs are no longer inconsistent (assuming we do Change how we handle index routes with nested components #3326 also)
  4. People can still do super clear absolute paths as long as they match their parent route perfectly

@taion
Copy link
Contributor Author

taion commented Apr 16, 2016

I'd say for (2), if we keep support for non-conflicting absolute paths, the bigger change is that things become simpler conceptually. The implementation ends up looking almost the same, it's just that we know that if a parent route doesn't match, then it's "cleaner" to say that child routes won't match either.

@taion taion added this to the next-2.4.0 milestone Apr 18, 2016
@taion
Copy link
Contributor Author

taion commented Apr 25, 2016

I'm thinking that we should actually move the matching logic into the route classes entirely.

@taion taion modified the milestones: next-2.5.0, next-2.4.0 Apr 28, 2016
@agundermann
Copy link
Contributor

As for the performance gains and simpler implementation, couldn't we also achieve this by transforming absolute routes during initialization, similar to how JSX is resolved?

@taion
Copy link
Contributor Author

taion commented May 29, 2016

I don't think so... we actually do need to look at the parent routes. I don't know – it's maybe not such a big deal in practice.

@@ -75,6 +75,8 @@ function routeIsActive(pathname, routes, params) {
const pattern = route.path || ''

if (pattern.charAt(0) === '/') {
// This code path is deprecated, but we the deprecation warning will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there is an extra we in this comment.

@taion
Copy link
Contributor Author

taion commented Aug 2, 2016

Not much point keeping this open. Need a better plan before it makes sense to merge this.

@taion taion closed this Aug 2, 2016
@taion taion deleted the deprecate-nested-absolute-paths branch August 2, 2016 16:32
@lock lock bot locked as resolved and limited conversation to collaborators Jan 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants