Hacker News new | past | comments | ask | show | jobs | submit login
React Router v4 FAQ (github.com/reacttraining)
159 points by clessg on Sept 16, 2016 | hide | past | favorite | 181 comments

I normally try to keep comments here reasoned and civil but the amount of churn in this library is almost so much of a joke that it should become a meme. At this point it's almost more expensive for me to continue updating than it would be to just fork the library and maintain the upgrades myself.

Any time I have to touch react-router I just resign the idea that I'm going to have to take at minimum a day to work out the bugs that pop up with every upgrade, (even minor changes).

> Why the huge change? (AGAIN?!)

> tl;dr Declarative Composability

The huge change is because the maintainers are apparently unwilling or incapable of either A. Creating something good enough on the first, second, or third attempt, or B. are completely oblivious to the needs of devs trying to create practical software and don't understand that project stability is just as important as a good API.

Thanks but no thanks.

I know. I hate it when people learn stuff writing free libraries to support new technologies and then release upgrades informed by what they've learned.

I've watched React Router grow from one-of-a-handful-of-experimental-routers-for-React-on-GitHub to the most well-known third-party library in the React ecosystem (tied with Redux). In that time, Michael and Ryan have learned plenty. They've also taught plenty. Libraries that experiment with their APIs, like React Router and React Motion, help all of us understand how to wield React better. I learned how to use contexts by dissecting React Router v0, when they were still an undocumented feature.

I understand the frustration that upgrading creates. (My first React project was creating an isomorphic server - I was definitely sensitive to changes in the routing API.) Still, I hate seeing a whinefest every time a free library makes a change that an app author disagrees with. You're always welcome to {fork it, build/use something else, help maintain and give feedback on API direction}. Michael and Ryan are enormously friendly and welcoming to external input.

Trying to embarrass the creators or turn them into some sort of open-source pariahs helps nobody.

One of the things I admire about the tech community is their willingness to just give away their code for free. This is a cultural fact that has underpinned such an enormous collective gain of everyone in the entire world that I get genuinely worried when I see people get that mad at open source maintainers.

I look at the scientific community and their inability to share their data with one another out of paranoia, publishing incentives etc... it's not just bad for science, it's bad for their community - their ability to enjoy each other's company on a daily basis.

So you know - I just feel you gotta be kind to open source maintainers. They didn't break anyone's app. They just released new code that you don't have to use.

Also, there is one massive part here that people are missing. From the release notes:

>We intend to keep supporting the 3.x branch indefinitely (published separately on npm to aid in migration), although there will likely not be any future major versions based on that code. 4.0 is the future, but we won't leave you hanging if you want to stick with 2.x/3.x.

It's not like they are pulling what Bootstrap did and just leaving everyone on the old version out to die. They are going to be supporting the 3.x branch indefinitely.

If you don't want to move, then don't! It's not going to suddenly explode, they will still accept changes for that branch, and bug fixes will still happen.

In fact, 3.0 is still being developed. I just pushed out beta.1: https://github.com/ReactTraining/react-router/releases/tag/v...

Glad to hear it! I'd recommend putting more info on your support of 3.x/2.x in the FAQ linked here for when other places eventually pick it up.

The only reason I knew that was because I took at look at v4 yesterday when i was bumping up some of my dependencies before our freeze.

With the recent Bootstrap issues still fresh in many's minds, and the already bad reputation that many think the JS ecosystem is "doomed" to continue, it would help to really drive home the point that you aren't just hanging everyone out to dry.

The guy is pissed and he has a legitimate reason to be so; he doesn't try to embarrass anyone, I guess. The lib authors may be the most friendly guys of the city, it does not have much to do with the issue.

In all fairness, this is a problem that plagues the whole JS ecosystem and not just this lib, but it's no reason not to mention it anyways.

Nailed it - I really do not understand what it is about the Javascript ecosystem (and particularly the React part IMO) but comparing it with the Elixir ecosystem where the underlying language is probably evolving faster even than JS is, Jose and Chris seem to make 90% the right decisions up front and not have to make massive fundamental rearchitectures every 10 minutes.

It's classic shoulders of giants. Elixir is built on Erlang, a 30 year old language/system/community, and a vast array of knowledge on how to do functional/concurrent/systems programming.

Web apps were a completely different beast as little as three or four years ago. Despite the incredible progress of the last few years we still don't know the best way to go about architecting SPAs, of course things are going to be a little hairy.

Not trying to defend anyone here but I think you're making the wrong comparison. React (the library) isn't changing. Just like Elixir, JavaScript (the language) is changing for the better and almost everything is backward compatible. What folks are upset with here is react-router, an optional, third party routing library dependent on React. Authors should be allowed to improve their own projects otherwise they become stagnant as the libraries and languages they depend on evolve. It's why semver exists.

Much of React-Routers problems can be traced to the fact that it uses React components as its API. Yes, there's an alternative API in v3, but it doesn't seem to be very well thought through and is hardly ever used in examples.

Another issue with React-Router is that fundamentally in a web-based system, the router is the core of your framework (middleware, hand-offs to controllers/views, etc. are all built around the abstraction that the router sets up). With React-Router embracign React Components as their API, it means that your entire application must be built to the same abstraction---entirely within the React system, with components nesting other components.

I feel the problem of making a large javascript application client-side is best dealt with by keeping React as the view only, and putting everything else (router, dispatcher, models, etc.) in the form of another abstraction and not defaulting to component based architecture because that's simply what React does.

I agree. I don't necessarily want my routes to be declared in react. I'm currently looking into using router5 (https://github.com/router5/router5). The library also has integration plugins for react and redux.

Also, check out https://medium.com/@mweststrate/how-to-decouple-state-and-ui.... Michael Westrate talks about using your state container to control routing, instead of letting the components do it then syncing current route to state container. He is the author of mobx and uses it in his example, but I imagine it would work for redux scenarios too.

I've seen that article. :)

It came at a great time, in that it really crystallised some ideas I had been having about the friction of using React-Router. So I buckled down and wrote my own router component with HistoryJS & Crossroads.

Surely there's more fog of war when coming up with better browser-side abstractions than on the server-side.

> I've watched React Router grow from one-of-a-handful-of-experimental-routers-for-React-on-GitHub to the most well-known third-party library in the React ecosystem

> Libraries that experiment with their APIs, like React Router and React Motion, help all of us understand how to wield React better

If I read this correctly, you believe that it is still in experimental phase? I don't have any problem with people learning and experimenting, but using major release versions a your petri dish is obnoxious for all the thousands of people using react-router even if it is convenient for the core maintainers. There is a difference between an upgrade and an overhaul, with the extent of the changes over V2,3,4 they might as well have just released a completely new routing library or just maintained an experimental branch to figure out what actually works before releasing a series of major breaking changes in quick succession to the greater world. I'm aware that breaking changes are necessary sometimes, but rapid churn is not necessary, esp once you are post 1.0 release. If there were some burning reason to release an upgrade then that would make sense but this release does not even address some of my major pain points with the API.

I also am not complaining about the cost and personally I don't see any validity in the "it's free so I am beyond reproach" mentality that open source people seem to have. What makes you think that I would thank someone for something that was free even if I didn't want it? Or that anyone would for that matter. Thanking people regardless of what they did, just because they did it for free, is one way to erase market signals which govern the direction of open source projects. I would rather just be candid and honest so that maybe people will remember that me and other devs in general are negatively impacted by breaking changes and therefore will consider keeping projects stable.

I also didn't "try to embarrass the creators" and the only person on here to made this personal was you, who decided to name the maintainers by first name.

> personally I don't see any validity in the "it's free so I am beyond reproach" mentality that open source people seem to have. What makes you think that I would thank someone for something that was free even if I didn't want it? Or that anyone would for that matter. Thanking people regardless of what they did, just because they did it for free, is one way to erase market signals which govern the direction of open source projects.

Damn. Most of the time people follow their reasoning with, "I am paying for this, so do the stuff I want exactly how I want." But, This is the first time I've seen someone using the free-market to excuse being a dick to someone who's giving their work out to the world for free. The amount of entitlement mentality in this person is so unreal, I'm literally almost exploding in rage here, because I can't believe anyone would treat anyone else like that.

To the maintainers: 99.999% of people out there are not like this person, and we appreciate your work very much. Thanks for putting that work out there. Your effort is also unreal, but a kind version of unreal!

Or you could just not use it, or follow your original thought and fork it and maintain the older version. It's MIT licensed, so you're more than welcome to do whatever you want.

Instead of doing any of the things that'd require work (like the creators did), you insult them. They must be oblivious or awful at software, right?

> The huge change is because the maintainers are apparently unwilling or incapable of either A. Creating something good enough on the first, second, or third attempt, or B. are completely oblivious to the needs of devs trying to create practical software and don't understand that project stability is just as important as a good API.

I know. I hate it when people learn stuff writing free libraries to support new technologies and then release upgrades informed by what they've learned.

I think there is some responsibility incumbent on the person implementing the library to actually vet the library for good design and pattern implementations, to ensure they are not adopting someones learn as they go projects (if that is an issue they are trying to avoid). This seems to be endemic in the JS space, as an example, I was surprised at how many people jumped on Angular 1.0 give it's serious design flaws that where evident with just a cursory look at the overall architecture of the software.

If that were true why the pathological method renaming between versions. Maybe this is the equivalent of a 1.0 and now they are finally going to keep things stable but how can you trust that "this time".

If what was true?

Routing stateful apps using string URLs is not a solved problem. Which thick-client app gives you a universally shareable string that restores it to a specific predictable state? How is it even possible? It took a confluence of web technologies, however ill-wrought, to make that possible today.

No one has yet figured out a clean abstraction that solves this - yes it is hard to imagine that we still have new problems that were not solved in the 1960s by the Greats. This is not a computer science-y problem; it falls into the spectrum of craft and art than science. It'll be beautiful when it is framed correctly and an elegant solution comes out. From the looks of it, the authors of this library (along with the rest of the client-side router ecosystems) are the closest.

The FAQ satisfactorily answers why they are trying this approach - React brought the concept of 'mounting' UI elements, and it applies equally well to routing as well.

I do share the pain of having to keep up with a changing API; and it is especially biting when it feels gratuitous (which I think is not at all the case here), but let's chalk it up to the cost of being in the bleeding edge, working in one of the most well-paid professions in the world.

This is a really logical and thought out response. The evolution with React Router isn't meaningless. It's simply good people trying (and succeeding imo) to innovate and create good, well-formed software.

JavaScript as a language has a lot of churn, and many times unnecessarily, but there is nuance.

> Routing stateful apps using string URLs is not a solved problem. Which thick-client app gives you a universally shareable string that restores it to a specific predictable state?

Google Maps seems to have solved a version of this problem. There is a unique URL for every position and oriention of your view of the world, including street view.

But even then it doesn't log you in as the user who sent you the link. (That would be crazy.) The link will probably also not include any user-specific display preferences. If Google Maps had a "kilometers from you" widget in the corner, you would not expect that value to be reconstructed from the URL.

So really URLs are not keys to the entire state of the app. They represent a "location" which is both abstract and very specific to the application.

Personally I think of the URL as just another input to the state of the application, really not that different from user events, HTTP responses, etc.

> but let's chalk it up to the cost of being in the bleeding edge, working in one of the most well-paid professions in the world

Slightly off-topic, but I have observed that front-end engineering posts seems to have lower salaries compared to back-end engineering posts for the same level of seniority. My working theory is that there is a higher supply of front-end devs - most of the self-taught devs I've encountered work on the front-end (Flash -> HTML/Javascript, or Designer -> dev).

It all depends where you live and what is considered front end or web developer. In NYC if frontends get paid less it's only $10k less at most. They're still making up to six figures with less than ten years of experience.

The only API that works well and give you all the flexibility is the one that the browser exposes. If you stick to something that is close to how the browser behaves, you should be fine.

In the React ecosystem I have seen that people sometimes want to abstract too much with no real pragmatic advantages. The result is that the abstraction become verbose to use and get in the way for coding things that produce a better user experience. Things that used to be simple to build.

Keep it simple. Make it more complex only when it is necessary.

All fair points, but we still have the problem of giving our users a URL to our rich web app which can take them into a node inside a nested state hierarchy. And not all applications can be purely server-side. You can't for example build a spreadsheet on the web as a series of request-responses.

I'm with you. I'm so sick of this library. About the only thing they got right the first three times was the name of the package yet they have dragged everyone through countless iterations of regurgitated API churn to keep it instead of just creating a new one.

Maintaining react-router and keeping up to date for a production site is a full time job I don't want.

I realize I sound like the a whining open source leech but there is a huge opportunity for a stable library to emerge and capture mindshare here.

Where is Facebook during all this? Someone needs to step up and solidify this critical react ecosystem component and it seems like it should be them. Obviously.

2.x and 3.0 are not deprecated at all. We're working on another release of 3.0 in fact (hopefully a beta before we go to final 3.0.0). We plan on supporting that version indefinitely, as there is a whole ecosystem of projects and libraries that depend on it. We're not pulling the rug out from underneath anyone and running 3.0 isn't "running the old version".

4.0 represents what we think is a great building block for routing in React applications. But it is not a hard requirement to use it. We think people are going to be more jazzed for 4.0, but there is so much stuff built around 2.x/3.0 that it would be moronic for us to force you into this new structure.

Please, keep your deps at "react-router": "< 4.0.0" if you want to. You won't be penalized for doing so, I promise you.

It's a little late now, but I might suggest in the future of that rather than radically change an API interface, even between major versions, you launch it as an entirely new package. While I really appreciate the work that you guys have put into this library, I think what everyone is really frustrated about is the heavy change between versions. This creates a lot of logistical headaches and perception problems that have upstream consequences, some technical and some political.

There is now ui-router-react, the React version of UI Router for Angular, an extremely popular router for Angular 1 - it is such a defacto solution for Angular that even Google uses it, and the core got extracted to be agnostic to Angular.

Per comments from the React devs, Facebook handles routing needs with their own internal stuff. They don't use anything like React-Router themselves, so they have no need to build or open-source something like that.

One thing worth adding is that along with Redux, React Router has been vocally blessed as the right solution by Facebook employees. This means it occupies an unusual position within the ecosystem in that it's a de-facto standard, and fairly critical to many projects.

It definitely suffers from a documentation problem (the new examples are genuinely great, but previous versions were very light on practical examples and best practices).

Thankfully, I've never had to deal with routing in any of the applications I've worked with. (Primarily internal stuff that is true "applications in a browser", rather than stuff addressable by sub-URLs.) So, I've managed to avoid all this complexity. Wasn't until relatively recently that I even understood what client-side routing actually involves.

Personally, I think that routing in general is one of the major causes of "Javascript Fatigue", and is proof that building complex software is inherently complex.

I will say that despite its "de-facto standard" nature, there's certainly a number of other options out there. I keep a list of Redux-related addons and utilities, and there's a couple dozen entries in the "Routing" category (https://github.com/markerikson/redux-ecosystem-links/blob/ma...). Again, I haven't used any of them myself, but they exist. And that's _just_ "libs that relate to routing and Redux", much less "libs that relate to routing and React, or routing in general".

If you are interested, this is what my team uses and it works REALLY well for us. It uses the standalone Express 5.0 router, so any pattern that works in Express works here.


I was just talking with an acquaintance who's at a company that invested millions of developer-dollars in cutting-edge tech. 7-10 years later, after a long period of a few developers keeping everything together with duct tape, the whole thing is getting thrown out.

Why? Well, some of it's solid code. That might be worth keeping. But some of it's technologies that fell out of fashion. And there's a bunch of stuff that people wrote in a frenzy, so there's a bunch of tech debt. And even if they stripped it down to the bones, there's a lot of upgrading to do just to get back to where they could do new work with modern libraries. From the business perspective it was easier just to glue together a bunch of outsourced services.

I'm sure those developers all meant well by picking cutting-edge tech. But as Dan McKinley says, we should generally choose boring technology [1]. As you describe, the costs of keeping up with interesting things is substantial. On rare occasions, it's really worth paying that cost. But, mostly, as with my acquaintance's company, the costs can accumulate while your attention is elsewhere, pushing code bases into a sort of technical bankruptcy.

[1] http://mcfunley.com/choose-boring-technology

What would be the boring technology to pick for starting a web + backend project today?

Several boring but good things

Spring Boot (Java) is really simple and boring yet a lot of capabilities underneath

Also, ASP.NET (c#) - similar deal

Django or Flask (Python)

Backbone.js, jQuery, Bootstrap (JS front end)

Express (JS backend)

Sinatra (Ruby)


Maybe Angular or Ember or even basic React+Flux in the front end if you can contain your enthusiasm

For hosting, find a boring PaaS and avoid the container mud wrestling

For pity's sake use PostgreSQL or MySQL, MongoDB burns

For my first project ever on Java - I did an API on Spring Data Rest and connected to a db I designed on Oracle (requirement).

I was pleasantly surprised at how much functionality I got for free once setup. I probably spent as much time on setting up Oracle and xml/config stuff as dev but it was still super fast to get a solid API built.

I really like how you, tomca32, and nous all are suggesting multiple language/framework options. I think a lot of the way these technology choices go wrong because people want to pick the best option, rather than a good-enough option that matches local conditions. The former strikes me as a local, narrowly focused tech optimization; the latter, looking at the bigger economic picture of the project.

Django or Flask (Python) Express (JS backend) Sinatra (Ruby)

What would you suggest out of these for quick prototyping and just side projects?

Postgres and Flask. Create it as a package, not an individual module. Front-end it with gunicorn and nginx. All monitored by supervisord.


Bottle (Python). It's very minimalist and tries very hard to get out of your way, but it usually provides enough for prototyping and quick spur-of-the-moment things.

The latter is also when you might appreciate the fact that its markup language is really just embedded Python (PHP style) - you're trusted to not abuse the power, but you define what "abuse" is.

Flask is awesome, sure, but you will have to do a lot of mundane stuff with Psycopg2 (may all gods help you if you choose to dive into sqlalchemy!). OTOH, Rails ORM is awesomely simple and just works for 95% of the cases.

There is no PHP6. Went from 5.6 to 7.

Yeah I meant PHP 5.6 , my bad

Probably PHP and plain JS, which is why I think that argument doesn't make sense. New web stuff is currently so much better than the old alternative that dealing with tumultuous stability is often worth it.

I think there's a middle road. What you're mentioning is pretty extreme. Rails/Django/Spring and Angular/Ember are all considered boring and very stable while not nearly as outdated as your example.

Care to show me your math on that over a 10-year time scale?

I'd be curious even to see it for the technologies you mention. But as others point out, there are plenty of things newer than PHP that have become pretty boring.

Is it? I used to happily make very complex sites using Apache Wicket on top of Java. It lets you make composable, extensible components (including inherited markup). It is type safe (the cools kids are finally rediscovering how important this is for maintainability with Flow & TypeScript). It supports replacing components using AJAX. Sure, it's not great for client-side SVG rendering or the various other cool things you can do with React and co, but hand on heart, I can't honestly say I find doing all this stuff in JavaScript to be "so much better". Quite the opposite for the majority of intranet-type sites, in fact.

python/ruby/java on backend. React/Ember/Angular on front end. The core libraries are relatively stable, it's mostly supporting libs that will burn you if you aren't careful.

Rails on the backend. Angular on the frontend. Both are big, stable frameworks with tons of support, plugins, thousands of tutorials / SO Q&As. Whatever problem you encounter with those, somebody already solved it.

This is the case with any mature framework. Rails and Angular just happen to be my favorites, but Django, or Spring and Ember can probably work just as well.

Angular 1 to Angular 2 anybody!?

If you are using Rails, Angular is rarely necessary from my experience. Even if you have a lot of SPA-type functionality, jQuery can handle it pretty well in the asset pipeline.

I agree with that. I felt that the question really asked what frontend boring framework would I choose, but you are right.

I try to avoid having to put up Angular or anything big on the frontend and just scrape by with jQuery. However, when the interactions are supposed to be "rich" and have a lot of animations, drag/dropping, complex forms that validate on the fly, etc etc...things can get really complex. Then you're back to the old dilemma: you are either going to introduce a full-fledged framework, or write one yourself. In those situations, I pick Angular.

- Angular 2 also looks fine, but that defeats the question which asked about "boring", stable frameworks

Rails and jQuery. Seriously. This is at the top of list of the most maintainable, well documented web app methods that exist.


One of my favorite articles. Also another argument for why we need a boring, stable, un-opinionated, cross framework compatible routing library.

> At this point it's almost more expensive for me to continue updating than it would be to just fork the library and maintain the upgrades myself.

Ok...what's holding you up?

I get the frustration, but if you like an older version you learned, just stay with it and maintain it yourself. Or do your own thing completely with another routing solution. Or roll up your sleeves and write your own. Maybe in a year, if the new version still looks like the way to go, put in the effort to switch over. You have a multitude of options.

People act like the authors of the library are intentionally toying with them. And this is for something that presumably no one has paid for!

The sense of entitlement that erupts every time some non-contiguous jump in progress happens is the far worse meme, to me.

Also, they will be supporting the v3 version of the code "indefinitely". So it's not like he/she would even need to fork the project to continue to support the old version...

I've been using react-router 0.13.4 for almost a year in a project and it works perfectly. I found no reason to upgrade and am now glad I didn't bother.

Same here. I don't understand why people always feel like they need to have the latest and greatest version, and then complain when shit breaks.

How about this: if it ain't broke, don't upgrade.

No way, I can't do that! I'll get ridiculed for not being on the latest and greatest, and if I complain and take shots at the people building critical code for me to use for free, I'll get pats on the back by my peers!

Magpie-Driven Development at its finest!

I have to agree with that.

The javascript ecosystem in general is extremely fragile.

I have lost weeks and weeks worth of time investigating how X and Y silently broke again.

And I say that as a hardcore webdev who is very well familiar with Javascript.

Sometimes just makes me want to kiss it goodbye and go back to server or backend development for some sanity and stability.

> I have lost weeks and weeks worth of time investigating how X and Y silently broke again.

How does code just magically break on it's own? Either you did something wrong, or you're keeping details back. Code doesn't just work today and not tomorrow on it's own.

Stop blaming others for your mistakes.

My guess would be he/she did not lock the versions in package.json, but used "wildcards" (I consider `1.x` a wildcard.) Happened to me once, took about a day to figure out. I really dig `Gemfile.lock` in Ruby land for this purpose.

So I was correct in saying they did something wrong. :)

npm follows semver and expects libraries to do the same, whether they do or not is up to the library author, but npm can't know if the library does or not. Therefor the user didn't pay attention to the library they are using and blindly installed it and set constraints that caused breaking changes to get into their code. Once again, not the ecosystems fault, but the developers fault.

No you were not, what I was referring to had nothing to do with locking down version numbers.

I said "fragile". That doesn't mean something wasn't objectively "my fault".

Yes the bytes don't change themselves, I was the one making some changes here and there so in that sense it's my fault. But that's a very mechanical and shallow way to think about it.

Javascript as a language and ecosystem makes it extremely easy to create mistakes. In that sense a mistake that I make is partially Javascript's fault too.

Some people look at what I said and think "programming languages need to be better" and some think "humans need to be better".

The people in the second group don't help moving things forward. They just blame people for not being "smart enough" until the people in the first group set a new standard for what things should look like.

I'm with you. First when I thought of building a SPA application with React on my side project; I tried React-Router, the API was not that easy to grasp at first for me.

Then I have build my own router with `popstate` event and I'm quite happy with it. All the navigation history is pushed to redux. It turns out that it works really well for my needs and application.

We did something similar that uses the Express router: https://github.com/wesleytodd/nighthawk

The one thing we didn't do was layer on top of a flux solution. Seemed more future proof to not tie to anything other than a routing style. If you wanted to do that with our solution it would be as simple as writing an action to do the url change.

I built a React app for a large Ecom site recently using the same strategy. It handles all URL updates with the History API, and simply AJAX loads the same URL with a query param to hydrate the app with JSON. Works really simply, and doesn't require Redux, Flux, or React Router.

Have a link to your router?

Sorry, no. However, you can find the same pattern being used in the sound-redux project-https://github.com/andrewngu/sound-redux

>The huge change is because the maintainers are apparently unwilling or incapable of either A. Creating something good enough on the first, second, or third attempt

Well, it was "good enough" to be the #1 used solution and be adopted by almost everybody in the ecosystem, even if it wasn't "perfectly nailed" the first, second, or even third time. So, there's that.

If there are some better developers out there that can do it better and with less churn, where are they, and where's their project?

>B. are completely oblivious to the needs of devs trying to create practical software and don't understand that project stability is just as important as a good API.

Well, given the rate of churn in the NPM world, they aren't unlike anybody else...

This is one of the major reasons I try to stick with more well established libraries when I can. For example, when choosing our teams universal routing solution, I used the Express router instead of going with the NEW SHINY react router.

Of course this did mean wrapping it for use on the FE, but that was as easy as copying code form Page.js (another old school project).


If you're sick of the churn, I've been maintaining Andrey Popp's original React-Router-Component [1] for the last few years.

It's a simple router that hasn't changed much. I've tried to keep it extensible and simple.

1. https://github.com/STRML/react-router-component

You guys should switch to Ember, you never will have this problem and you get the best router ever. :)

Yeah, instead of this problem Ember will give you other problems:


Maybe should switch to jQuery, then no router was required. lol

>At this point it's almost more expensive for me to continue updating than it would be to just fork the library and maintain the upgrades myself.

I got burned by this in my last big project, we resigned ourselves to never upgrading past 1.0.0-beta4.

There's a big difference between breaking changes which resolve real pain points in a language/framework/library, like the break between python 2 and 3 and changes that are just for the fun of it, because someone "felt like it was better". I like to view developing software as an investment. You are spending time and money outright, and there is an implicit cost in foregoing other opportunities when you make a technical choice.

Investing in react-router is like investing in a clown. It's a total toss-up. The maintainers could all move on to whatever other hip lib and finally it will be stable, or you can continue betting large sums of money on what is basically a coin flip every 6 months: Are they going to screw with the library again (yes) and will it cause a bunch of bugs in my program (probably). It's a bad investment, esp if you try to upgrade. The ironic part of this is that honestly I feel like the V1 API is the best out of all of them. If they had just iterated and brought breaking changes that were actually needed instead of just those that they felt might be fun, the project would be much better for it in my opinion.

(I know python <-> react-router comparison is apples to oranges but bear with me)

I empathize with your frustration but please consider that changes in RR were not done "for fun". They were done to solve plenty of use cases that few (any?) routers in JS ecosystem ever had to deal with (universal rendering, avoiding waterfall of requests, animations).

Solving each of these problem introduced some awkward APIs, but the community demanded them with a passion just like in this thread. We all built and learned.

This rewrite is motivated by: (a) knowing the spectrum of use cases, (b) throwing out non-composable APIs that made it hard for everyone to extend the router, (c) eliminating a class of bugs caused by router trying to "orchestrate" everything instead of letting React do it.

It was not obvious to the authors how to do it from day one. It was not obvious to me or anyone else. Everything is easy in hindsight ;-) It's sure rewarding to solve these problems for the authors, but this has nothing to do with "fun" and everything with creating something future users won't hate.

All the churn in previous versions was caused by router fighting with React. Now it works together with React. Let's see how it pans out. And if you're pessimistic, keep using RR3, it's going to be maintained for a long time (you're not the only one using it ;-).

In the large scheme of things, is a day that big of a cost to move to a newer routing approach?

React Router and the problems dealing with minor updates was one of the several libraries(around 6) that sparked me to write the Sad State of Web Development

Do you have a better suggestion for a routing library at the moment ?

and imagine my surprise when I found out Node 7 exists already

sounds like hell!

Yep. I feel javascript library authors forget it's lines of code spent, not lines of code written. How would they feel about a contractor who had to rebuild their house 4 times? "Oh, they're really good about revving their design, this is great!"

Nope, library authors are trying to create a good product. When they fail, some of them try again. I'm an open source author myself, and comments like this make me think twice before sharing something. Maybe it's better I just keep that code to myself and not bother with the whole community thing. ;-)

I think a more apt analogy would be a public book library that gets rebuilt 4 times. On the 4th time though they built it alongside the old building instead of demolishing it.

Interesting change. If I understand correctly, basically you have a base component that updates fragments of the UI based on the route.

    const App = () => (
        <h1>Hello World</h1>
        <Match exactly pattern="/" component={Home} />
        <Match pattern="/about" component={About} />
        <Miss component={NoMatch}/>
Couldn't we take it one step farther and just use a switch statement? It seems like using pure JavaScript would be more idiomatic React. The URL pattern could be parsed in the data layer, and passed down as props. That way the components don't rely on global state, making them easier to test.

    const App = (screen, args) => {
      let content;
      switch (screen) {
      case 'home':
        content = <Home args={args} />
      case 'about':
        content = <About args={args} />
        content = <NoMatch args={args} />
      return (
          <h1>Hello World</h1>
It's probably just a matter of preference. Recently I started using React-Storybook, so I've become addicted to "dumb" components.

Thanks you are the only one talking about the new api style here, it seems very interesting. It is like the dual of the previous version where all routes were declared in the same place, here we dispatch the route fragments in the app. It will simplify nested routes, but I hope it won't "infect" the app with routing concerns too much. I've ranted before about react-router, maybe they should call it another name this time, I hope they will keep on maintaining the v3.0, the switching cost will probably be too much for my app.

One reason to go with components over a switch statement is so you can render a specific component on all '/about' pages along with an additional specific component on all '/about/team' pages. With a switch statement you can only match a specific branch.

You can still do nesting within a case, or add another case 'about-team': and add another {var} to your component. That's essentially what RR would do. React Router approach is probably a little cleaner, however.

It's more that you can get the information about the state of the browser or server's URL down deep into the component tree and then more easily act on it (with a few components, rather than a larger case statement).

It's basically idiomatic JS vs idiomatic React/JSX.

That's a fair point. Kind of like adding a redux @connect in a child component.

Edit: To the idiomatic point. The first thing that struct me when using React, was that instead of having to use a custom Component for a for loop I could just use someArray.map(). I see this as a similar situation.

This is actually a naive version of what I've been doing since I had to unwind a react/router/redux application once (I've since moved the components into an object and just reference it as component[value]).

While React-Router had a lot of great convenience features I found that it was surprisingly easy to roll my own redux-compatible version that fit my personal needs with a few lines of code and no additional dependencies.

For testing, you can wrap your component in <MemoryRouter> and that will work just fine (including links and redirects, for example).

I'm surprised at the number of negative comments about updates. You don't have to update. It will keep working. It's not like you're going to miss out and be left behind from some vast and vibrant react-router ecosystem. It's just a couple components that match strings up with other components and then barely matters to the rest of your application.

It's exciting that there are people out there experimenting endlessly to figure out the best APIs to build things with. Just because someone comes up with one idea doesn't mean they're wed to supporting it forever. Or for any amount of time: react-router v3 is open source and you can maintain it yourself if you like it or just want to stick with it but want more.

No need to maintain v3 yourself, they will be maintaining it for you.

>We intend to keep supporting the 3.x branch indefinitely (published separately on npm to aid in migration), although there will likely not be any future major versions based on that code. 4.0 is the future, but we won't leave you hanging if you want to stick with 2.x/3.x.

Disclaimer: I am a former Backbone-using developer who hasn't done much front-end work since React became so dominant. I just don't understand this project. I'm commenting to explain my confusion in the hopes that somebody else's perspective can help me see why React Router is helpful.

When React came out it was billed as just the "V" in client-side MVC. While just about everybody has their own understanding of MVC, my interpretation of the "V" was that it was about things you can see. So React was going to take my data and maintain a UI based on that data without thrashing on the DOM. Cool!

But nobody seemed to do that at first. They put HTTP requests all sorts of stuff inside the React component, and then handled the requesting, processing, and rendering as internal details to the component.

Then the Flux idea came around, which was (I think) to brand one-directional events as "actions" and then smartly cache/reduce an ongoing stream of actions into a single data structure that represents lots of potentially disparate parts of your application. This also made some amount of sense to me.

Surely there would be lots of things that could create actions: incoming DOM events representing a user's intentions, ajax responses that have potentially new facts about the world, websocket events, signals from the camera and microphone, and anything else that might cause a change in the overall state of the page. With the possible exception of DOM events, which the view should quickly translate into meaningful actions anyways, these actions are really not related to the "V" at all.

So what benefit would I get from authoring the logic of URL-change handlers in JSX? Wouldn't it be nicer to write some JavaScript that handles those events and transforms them into actions?

The V in MVC was a mistake IMO and it was eventually removed from their site.

Why do you think it was a mistake?

It's not how most people end up using React and it just causes confusion.

Flux (the data management architecture for react apps) eschews MVC altogether. Maybe that's related.

> So what benefit would I get from authoring the logic of URL-change handlers in JSX?

I don't get it either. I thought we were over describing program behavior in XML?

I'd love some backstory on this too. I (kind of) understand JSX for HTML, but declaring routing rules seems very far from that.

If you have a hammer everything looks like a nail?

Yeah, this is exactly my first impression (I've never really looked into any past version of React Router either).

Why is routing being declared in components in the first place? It seems counterintuitive. There are obvious downsides - so what are the upsides? The README gives no clues.

They are going to support the old versions "indefinitely". The FAQ doesn't mention it, but their Release notes[0] does. I'll copy the relevant part here:

>We intend to keep supporting the 3.x branch indefinitely (published separately on npm to aid in migration), although there will likely not be any future major versions based on that code. 4.0 is the future, but we won't leave you hanging if you want to stick with 2.x/3.x.


I think if/else statements with regexps, returning components, are my favorite "routing solution".

Ridiculously simple, no dependency on someone else's weird ever-changing ideas about declarative composable component-based route paradigms, no need to write your routes in a markup language, everybody understands it, extensible as hell, trivial to debug—it's a glorious cascade of beautiful advantages.

Try if/else today!

It's interesting just how long it can take to unlearn habits from previous programming experience and find a way to do things in harmony with the current tools you're using. Probably the more experienced and senior you are, the harder it gets.

To the contrary, it gets easier. Many of the new things are older things I've seen in different contexts. Some of the new things are a welcome relief from shortcomings if old tools.

It took me over a week to grasp how routing would combine with redux, async, react and then server side rendering.

We got there, but there just hasn't been a simple (to reason about) way to do this in javascript. Acknowledging that the current library is fighting (I would call it an anti-pattern) with react is probably a good step. Thanks devs!

One of the things that's burned me in the past with React Router is not just that the API changes from version to version but that documentation I'm reading at any given time doesn't indicate which version it refers to. I've wasted time trying to debug why things weren't working the way the documentation stated only to find that I was reading the wrong version of the documentation.

Some advice for anyone that hosts docs outside of the git source tree, make the version information clear. For example, the express documentation http://expressjs.com/en/api.html states very clearly "4.x API".

Looks interesting -- what's up with that Redirect component though ...? That seems all kinds of strange to me conceptually.

My mind is trying to justify it like this: Render me a component that's going to manage the state involved in transitioning to a new page ... I guess that kind of makes sense -- since a redirect is an inherently stateful process.

I too am confused by this. I found this GitHub issue [1] when searching for a withRouter HOC replacement.

1. https://github.com/ReactTraining/react-router/issues/3847

Okay. I understand that this library is kind of "learn as you go" project, much like React itself. But not make it on the third go… This is a part of React ecosystem that has not been reasonably "solved" (kind of like `redux` "solved" state-management good enough, or `express` solved server-side for Node good enough; and there are lots of iterations on those two), so if you want to start a popular OSS project, think hard about routing. (But really, think hard first!)

I also like this joke from github readme:

> Versioning and Stability

> We want React Router to be a stable dependency that’s easy to keep current.

I use routers that aren't coupled to the view layer, thank you very much. routers can actually be pretty simple.



^^ This is the one we developed on my team. No view coupling, uses industry standard underlying components (Express Router), and layers on top of existing applications seamlessly (aka, no view tie in points, just anchor tags).

That middleware is actually just a isomorphic render method, which uses express's render on the backend and react's render on the FE.

So that middleware actually requires a solution similar to what Nighthawk provides. The point was to keep the routing and the rendering separate, unlike what react router does.

Anybody else having trouble with the link that they provide to their "Quick Start" documentation?

I can't see all the code unless I zoom out on it:


Yup, seeing that too. They made some changes to that since last night when I was first looking at it. In particular they were importing `Router` instead of `BrowserRouter`. `Router` doesn't exist.

Also based on my testing you need to render a single component inside router, so wrap everything in a <div> like the basic example does: https://react-router-website-xvufzcovng.now.sh/basic

That version of the site will work best with Chrome. The newer version will fix for Firefox: https://react-router-website-xvufzcovng.now.sh/

The next build (now.sh versions URLs) will have both working. Sorry about that!

Quick question, is it necessary to render a single component within a Router? All the examples except the quick-start example seem to do so.

Yes, because we have to render props.children and normally Router is right under or near ReactDOM.render(), which only wants a single element from the component from the top of the tree. We were inserting a <div>, but that would screw over React Native users. So, unfortunately due to the structure of React, we have to enforce a single child.

This is improved a little bit in git, where we do a React.Children.only check: https://github.com/ReactTraining/react-router/commit/5a74d46...

Ah yeah adding that check should help. I wasted a good 20 minutes trying to figure it out the other day. Can the quick-start example be updated to have a single child? I would submit a PR but I was unable to find the repo.

So if you don't want to use react router what do you use for react client side routing?

You can always try https://github.com/ui-router/react Ui router has been the de facto router in the angular ecosystem for years. With version 1.0 the core lib became agnostic to angular.

I'm really interested in a good alternative for react-router if people have so many problems with it. I was going to use this in an upcoming project, but if there is an alternative that is better, I will investigate.

I na previous project we were using https://github.com/kriasoft/universal-router (or at least a previous incarnation of it). We had to write some code around it. Just to throw an alternative here.


My team uses this, we built it in response to most of us not liking the React Router methodology, and already using Express, it seemed like a good route.

What does it add on top of https://github.com/wesleytodd/react-express-middleware ? Are you using it for server side rendering, too?

A one or two years ago I met a person that was using the backbone.js instead of a flux implementation for React. They were pretty happy with it. My memories of the Backbone router are pretty good memories.

I've used page.js with React before was was fairly happy with it

https://github.com/visionmedia/page.js looks pretty simple. I supposed you are not using it for the server-side rendering. Or you have a route in express for any route on page.js. Correct?

If you are interested, that link I posted above, Nighthawk, actually is a port of Page.js for its dom and pushstate handling wrapping the Express router, so it is just as simple. Here is the bulk of the code taken from page.js: https://github.com/wesleytodd/intercept-link-clicks/blob/mas...

I started using react-router recently and I felt that some things were missing (like passing props to routes). I hope this release Will improve the API.

Thanks to all the devs that keep moving forward this wonderful ecosustem.

As far as I can tell, that part hasn't changed. But you're free to pass a HOC (Higher-Order-Component), ie.

    <Match pattern="/" component={() => <MyComponent someProp="yep" someOtherProp={myOtherGlobalVar}/>}/>

I am new to React Router. What is the alternative to managing routes on the front end when you're using only React (and redux) on the frontend and not routing on the backend in express or something?

Is there any other Router library for React which has a stable API ? We are most likely to include a router library in our application soon and we don't want something which changes frequently.

I've been asking myself if I really need it. The very first React project I ever did I managed URLs by myself like I would have done in jQuery/Backbone. Honestly, I don't remember it being that bad.

During the past year or so, as the "standard" React architecture has come to embrace keeping application state together in a global store, react-router looks a little out of place. Why should it maintain such a crucial part of the application state separate from the rest of the app? In reality, the best pattern for the future probably looks a lot more like "redux-router" than react-router.

I recently noticed that reactjs/react-router redirects to ReactTraining/react-router. Does anyone know why that is?

Because they changed orgs and Github redirects it for you.

Yes, but why did react-router move out of the reactjs org?

It's always been Michael and Ryan's project. They wanted to move it back out -- I assume to help promote their training business -- and that seems perfectly fair to me.

Further context:

Their org was originally called rackt (a rough portmanteau of Ryan florence and michael jACKson). When Facebook donated the reactjs namespace to the community, they moved it there alongside a bunch of other popular community projects.

React Router was the project that taught them React. Since starting it, they decided to quit their day jobs and teach React full-time. rackt (the sandbox of two Internet friends) is now ReactTraining (an actual company). As spicyj said, they probably moved it back to help build brand recognition and use their flagship product to add credibility to their new business.

They maintain React Router to help promote their training business? I suppose that could explain its instability.

No, that's not why they built it (they built it before starting their business) and I don't believe it's why they maintain it.

I just want to point out that whether they built it before or after starting their business doesn't really matter. It's definitely a part of how they promote React Training today (see: moving the project to the ReactTraining GitHub organization, or how many times react-router is mentioned on their marketing website).

Not that I have a problem with that; all the more power to them. Especially if it helps support development of these libraries.

After using react-router more than a year, I have to say it's a helpful lib, but the doc and the authors are not ready for serious business.

It's interesting that a large amount of churn seems to be an unfortunately common trait of frontend libraries.

Just a note: You can't scroll the docs (Chrome OSX).

Sorry about this! If you use the older now.sh link, it will work: https://react-router-website-uxmsaeusnn.now.sh/

It's fixed in git, Ryan just needs to push a new build.

Confirming I have the same issue.


How so? He seems very nice to me and people in general like him and his course.

Great! I removed React router from a project yesterday, now it seems an even better decision.

Edit: I didn't have any big issue with React router and don't dislike it. It just don't work well with clojurescript/rum. I'm now using a cljs lib called 'bidi' for bidirecional routing (data only) and a small logic to change content reactively based on selected route.

Same! react-router is the only thing I've dealt with in this ecosystem that I truly, viscerally disliked.

I'm curious, did you replace react-router with something else or are you managing the url "manually"?

With a tiny cljs lib (bidi) and some 10 lines of code to change content reactively

What are you using instead, can you recommend a nice alternative?

My team uses this: https://github.com/wesleytodd/nighthawk

Basically it is just the Express router wrapped with logic from Page.js for catching link clicks and what not.

We do universal rendering with a simple middleware and share all our middleware, rendering and route definitions on both the FE and BE.

As someone just arriving to React - should I just learn React Router v4?

I suggest you to learn React itself first. No Redux, no routing, just React itself. Build a few small apps to get a feel for it.

When you need routing, I suggest trying to use HTML5 pushState API. Figure out how to use it in React, and try to add routing to one of your apps.

After that, I think React Router 4 is going to be a great next thing to try. Get a feel for it and use it if you like it and if it solves your problems. I think RR4 is shaping up to be much better than previous versions.

Disclaimer: I work on the React team.

No. Avoid react-router. If you really need it (you probably won't), you'll know it. Do react-router last. Way last.

Hi, one of the authors of the router here :)

Try to insert routing only when you need it. When you're ready for a router, react-router is a great choice. Lots of people are already using it with great success, and you'll find a great community of people willing to help you out.

Yes, I like this. It's important to learn what react is and why it's good for handling state in a component before you start trying to build the routing of a full web app.

I would focus on learning React(maybe look into create-react-app). Once you're solid on that, then v4 should be stable enough to dive into head first.

Probably v5 at that point.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact