Readit News logoReadit News
n0us · 10 years ago
React Router works well enough but I've had a lot of problems using it. One issue in particular I've had with this project is that they change the API so frequently that it's often difficult or nigh impossible to find documentation on issues, how to do X, or access property Y. There are the official docs, but sections have been scant or incomplete, and in some cases wrong. Crucial information might be omitted or only found in another location. Reading other people's projects or old issues is a pain because there is example of using API "X" but now it is named "Y" and does exactly the same thing so you have to go look up the release notes to even find out if the issue is relevant to you.

My project broke the other day because when you provide multiple child components it used to create an object that was "this.props.children.component1" but now it just does "this.props.component1". But when you only pass one component it is still named "this.props.children" in spite of there only being one component. I was unable to find any convincing reasoning for making this change. Does exactly the same thing. Makes the interface less sensible in my opinion. Caused me to do unnecessary work to achieve exactly the same result.

I get that changes are necessary when they change functionality but a lot of times it seems things have just changed with no reasoning other than just changing for the sake of changing. Maybe I'm being unreasonable and overly picky but I wish they would just keep the API stable and make the changes behind the scenes.

taion · 10 years ago
Our top priority after we get 2.0 solidly released is to revamp the documentation and provide a better tutorial. The work that Dan Abramov has done with introducing Redux is a positive example to all of us.

As for the change to the case with using multiple named child components - we made that change because React upstream made it no longer valid to pass objects into this.props.children. It wasn't that we decided one way or the other that it was nicer to spread named children into top-level props; the old way that we did it (which for this case was arguably cleaner) was literally no longer supported by React, so we had no choice.

spicyj · 10 years ago
That doesn't sound right. You can pass whatever you want as props to a composite component; you just can't use objects as a list of children in a DOM component, but that's not what you were doing before. When Ryan Florence filed an issue with seemingly your same misconception, we told him the same and never heard back:

https://github.com/facebook/react/issues/5371

What am I missing?

cortesi · 10 years ago
This matches my experience with react-router. I use it in a few side projects, and I have the feeling that there's been a lot of "design-thrash" - every new release seems to bring a new interface and new ways of doing things, without much real benefit.
49531 · 10 years ago
Yeah same here. Using it in production has cost some time upgrading. Not looking forward to another upgrade just a few months later.
rileyt · 10 years ago
I couldn't agree more. I have used react-router for 3 side projects now, each time with a new interface and no real benefit over the last version, not to mention more outdated docs and advice.
bpicolo · 10 years ago
This has been an issue for me with the entire React ecosystem. Trying to get react hot loading working between all the expected latest packages last week was insanely hard.
timdorr · 10 years ago
Hey, I'm on the rackt team and work on both react-router and redux. I joined on around the time of the 1.0 rc's. I can't really speak to the pre-0.13 days, but I've been involved in this most recent rewrite pretty heavily.

A lot of the motivations from 0.13 to 1.0 were around the APIs very liberally mixing React conventions with plain Javascript conventions, with a dash of callback hell thrown in for good measure. In addition, getting access to a lot of the internal APIs for integrations with things like redux and relay was very difficult. So, there was a very large rewrite to better modularize the code and improve the semantics of the API. I think they got pretty close to a good goal, but obviously there was room for improvement.

2.0's motivations have been around further simplifying a lot of the API surface area, particularly in relation to the history sub-project (which is a wrapper around location.hash, HTML5 pushState, and pure memory location state histories). history (which was a peerDep) was a big problem because we tried to stay hands off from that API as much as possible. This ended up putting a lot of mental load on the user, because they now had to be aware of and learn two libraries. So, we're now wrapping things up under a single API provided via `this.context.router` and provided pre-built history objects so you can choose what kind of history (hash or pushstate) you want with much less code and overhead.

Another important thing in this upcoming version is backwards compatibility. We want to avoid the hassles you're having with things breaking all the time. If this version doesn't work with your code built for 1.0, then that's a bug and a blocker for release. We're following React's lead for post-1.0 versioning: https://gist.github.com/zpao/6e12ee0f46ce87af2287#versioning That is, we will release new APIs with each major version and deprecate but support any upcoming API removals. You'll have a chance to test against those removals by looking for dev-only warnings, but everything should work drop-in. As a bonus, we're also shipping a series of jscodeshift codemods to automatically upgrade your existing code to the newer APIs: https://github.com/rackt/rackt-codemod Check those out, because they're really cool and Jimmy Jia worked to make them a part of our upgrade path.

Now, as for your mentioned issue, that was actually a change in a rc version. Yes, changing an API in a release candidate is bad. No way around it: that's our mistake. There was a good reason for this, as it caused bugs with React.Children.map: https://github.com/rackt/react-router/issues/1968 The 1.0 release process was super-rocky and we're looking to avoid that in the future. For 2.0, our API is stable and works to the best of our knowledge. No additions or removals will happen before the final version, so the rc badge is being properly used this time.

We're also making sure our documentation for upgrades and general use are up-to-date and super-clear. The 2.0 API actually came about because Ryan Florence went to go make a screencast series and ran into many of the common problems with the 1.0 API. So, documentation drives our development pretty hard now. We still have a LOT to do, but we are working on it in earnest and my personal goal is to have some of the best documentation out there when all is said and done.

If you have any other suggestions, criticisms, or questions about the APIs, please get in touch on Github via an issue or hop on the Reactiflux chat on Discord. We're all nice, reasonable guys who want to help and make this a great library for both power users and beginners alike. We need more feedback like this so we can make sure we're moving in the right direction. I promise we won't bite!

cageface · 10 years ago
This ended up putting a lot of mental load on the user, because they now had to be aware of and learn two libraries.

This problem is endemic in the JS world these days. Sure breaking things up into independent modules is a good thing up to a point. But having dozens of little dependencies for every library with their own compatibility issues gets unmanageable very quickly.

dustingetz · 10 years ago
You are free to evaluate the stability of any open source projects you would like to use, and if they provide insufficient value, you may get involved, or donate, or use any of the competitors like Backbone.Router or write your own, or otherwise add value to the ecosystem yourself.

Fast paced innovation is good. If you don't like life on the edge, it's not like these problems were unsolved last year. Use those solutions.

fvargas · 10 years ago
FWIW, `this.props.children` is an opaque data structure and should be treated as one.

https://facebook.github.io/react/docs/top-level-api.html#rea...

arrakeen · 10 years ago
after banging my head against react-router for a side-project the past couple of weeks, reading that one of their motivations for 2.0 was to clean up the interaction between history and router was a sigh of relief. looking at the docs, however, made it clear that they are doubling down on their strange and confusing history API:

  import { useRouterHistory, hashHistory } from 'react-router'
  // useRouterHistory creates a composable higher-order function
  const appHistory = useRouterHistory(hashHistory)({ queryKey: false })
  <Router history={appHistory}/>
if i wanted to change the scroll behavior of router, then i'd have to do something like this:

  import useScroll from 'scroll-behavior/lib/useStandardScroll'
  const appHistory = useScroll(useRouterHistory(hashHistory))({ queryKey: false })
how does this make using router/history any clearer?

i LIKE react-router, i think it's pretty damn good, but I just don't understand the rationale for their API choices. combine that with the velocity at which they're changing the APIs, it makes me wish that they'd just take their time with the design

taion · 10 years ago
Your code example is actually wrong. The intended API use looks like:

  import { Router, browserHistory } from 'react-router';

  const router = <Router history={browserHistory} />;
One perk is that you can then navigate using the singleton if you want, e.g. with

  browserHistory.push('/foo');
The scroll behavior stuff is definitely messy; I haven't had time to clean it up. The nice thing about OSS, though, is that the rest of you are all free to contribute changes.

roblabla · 10 years ago
I'm personally averse to the whole singleton thing. What about server side rendering? You don't want the history to be shared across requests.

Most projects already have their own ways to pass dependencies (through DI or whatnot), and I can't help but feel like providing those singletons is going to end up messy.

biscarch · 10 years ago
React Router has been iterating towards better APIs for advanced use cases (server-side rendering, code splitting, relay (and other lib) integration, etc). Having used it in projects spanning the above use cases, the evolution of the API has been welcome change.

I'm also happy to see codemods and other AST manipulations (such as babel plugins) gaining popularity. Similar to eslint's --fix, codemods are making repetitive changes easier across large codebases.

dominotw · 10 years ago
I skeptical of benefits of declarative routing. My project got much simpler after I got rid of react-router.
Bahamut · 10 years ago
I'm skeptical of this as well, and while I had no problems with react-router on a side project, I have misgivings with the router being coupled to JSX - IMO, this is an unnecessary coupling of what should be service logic to components.
acjohnson55 · 10 years ago
It's not necessary at all to use JSX to describe your route configuration. Just use POJOs instead.
lomnakkus · 10 years ago
Could you offer more details? Why are you skeptical? What did you observe to come to this conclusion, &c?
crossman · 10 years ago
I'm curious to hear about what gains you saw from dropping it and how you handled rendering
albemuth · 10 years ago
It's a single component app and state does not change at all, in fact, we should be skeptical of React too, terrible for static HTML.
druska · 10 years ago
You made it seem like this is released. Right now the official version is v2.0.0-rc4.
tbrock · 10 years ago
I think it may be time for the community or Facebook to write something that replaces react-router.

It has been extremely difficult to build something on top of it and keep current. Pre-1.0 I can understand the API thrash but 1.0->2.0 in a couple months?

Facebook should carry the torch here and write a standard router. This is a core component critical to the success of React for any applications more complicated than a dashboard.

insin · 10 years ago
I don't undestand this expectation, there's nothing magic about 1.0.

They thought they had the API figured out for various use cases beyond the core routing functionality, but it turns out they didn't.

In addition, 2.0 is supposed to be backwards-compatible for end users and they're providing codemods to help you update when it's convenient to do so.

linkmotif · 10 years ago
There are aspects of React Router that are annoying, but I am glad not to be writing code for matching routes. Works for me.

Also a fan of https://github.com/relay-tools/react-router-relay, because Relay is great.

taion · 10 years ago
What do you find annoying about React Router?

If anything, working on react-router-relay has only made me appreciate React Router's design more.

A lot of the changes in 2.x are specifically from lessons we've learned in building react-router-relay and other integrations, but they're closer to refactorings and code reorganization than to wholesale rewrites.

linkmotif · 10 years ago
Generally what many others have said: that the API has changed a lot.

Specifically I didn't like it when named routes were removed.

But hey—it's open source. Sometimes I get worked up about this or that, but then I remember that all of this I'm getting for free and I must be grateful.

shabbaa · 10 years ago
I'm glad to see this thread and some debate about react router and it's features and ways it could be better. Too often any react critisism is attacked almost fanatically.