React Router: Version 1.0.OH NO!

Trying to fit in with the cool kids on the block, I decided to dabble in the hottest-of-hot front-end libraries to date, REACT!

Identifying myself as a visual learner with a keen eye in disguise, I decided that coding along a video tutorial (in react-router@0.13.3) was the quickest way to get started.

Confident in my approach, I rebelliously installed react-reactor@1.0.0 instead to throw myself in the path of the abyss known as “major-reversion-deprecation-hell” or “backward compatible-wha”?

About 10 minutes into the video tutorial, nothing worked….as expected.

  1. React.render is deprecated, use a separate NPM module (react-dom)
  2. React Router’s Handler, DefaultRoute, NotRouteFound, name routes, RouteHandler, etc… doesn’t exist.

It’s a simple fact-of-life that 25% of my new career is dedicated towards reading through documentations or getting on that Google StackOverflow game, and off googling I went.

A few minutes later, I stumbled across a considerate “maybe-you-need-to-know” version 1.0.0 document (from the React Router developers).

Gunning through the deprecated changes, I reloaded my app and voila, it worked!. As I sat smiling and semi-proud of myself, I resumed the video for a few moments until, in the corner of my eye, I saw something strange.

what is that query string?

I’m familiar with the client-side hash tag routes from Angular, but where did the query string come from?

Back I went, google-hunting the digital-forumiverse for an answer.

A hint Watson!

The sniper-esque keyword accuracy of my search terms returned something that looked incredibly helpful.

Turns out, a dependency that’s not included with React Router’s module is required to fix the URL eyesore.

“Why do I need to manually download another module that is pretty much required for React Router?”

I don’t have the strangest clue but this is one of those “doesn’t matter at the moment” questions so let’s get on wit it as progress waits for no one.

NPM i history -S

According to React Router’s document, the following is one form of ES6 implementation to fix the ugly URL.

import createBrowserHistory from 'history/lib/createBrowserHistory'
let history = createBrowserHistory()
render(<Router history={history}>{routes}</Router>, el)

Using Gulp + Browserify + Babelify@6.4.0(version 8 has React bugs), ES6 whines that the import statement has to be the very first line.

Waa Waa Waa!

Really? Has to be?

Suddenly overwhelmed with the urge to be overprotective of my first, I conjured a plausible conclusion that this approach was not clean…somehow.

As Babelify’s sirens continues to wail in the background, I made a commitment to “F’ that” and “use what we already know” to CommonJS design pattern this thang.

You may also use Reactify + Es6ify instead of Babelify during the Browserify transform

According to the document, the following is a possible CommonJS implementation.

/ or commonjs
const createBrowserHistory = require('history/lib/createBrowserHistory')

Not bad per se, but what’s with the require(‘module/path name/function)? Seriously super fugly and not what I expected.

And if the module’s folder structure changes?

Frustrated, I did what any soul searcher would do for a clue, I resorted to the trusty old console.log to see what’s the dizzle is with this history module.

console.log(require(‘history’))

Behold, the module contains a createHistory property that returns a createBrowserHistory function, so why not just avoid file path insanity and use:

const History = require(‘history’).createHistory;
let browserHistory = History();
Oh yea baby!

Success! I’m beginning to feel manly with each passing moment.

BUT WAIT, THERE’S MORE (examine closely)

Where are the Speaker properties?

Why is it blank after Speaker, and what happened to the value that’s supposed to be populated?

Returning to the Google-hunt, it was discovered that React Router’s RouterHandler is deprecated, there is no way to pass states to a child.

https://github.com/rackt/react-router/issues/1857
“Router now automatically populates this.props.children of your components based on the active route.”

Fine, I can’t pass the state directly but I can disguise-wrap the state within an object and pass it as a property via {appState: this.state}.

Parent Class/Component (this is the bad “I was an idiot before way”)
(Edited Jan. 2nd 2016: You may use the spread operator to pass states to children

I went with a suggestion to have the children reference an “appState” object (this is wrong, please see update above using the spread operator {…this.state}).

Child Class/Component

Behold, the power of React Router v1.0.0 in all its glory.

Voila!

Here are are supporting code-snippets to help demonstrate.

This is the main jsx

A little breakdown would also help those that are skim-browsing this page:

  1. <Route Path=”/” component{APP}> forces all root path to hit APP component that is a wrapper class for the 3 routes
  2. IndexRoute sets the “first-class” route to the local module “Audience” component. More info here https://github.com/rackt/react-router/blob/master/docs/guides/basics/IndexRoutes.md
  3. path=”*” is used to handle unknown routes and redirect to the ‘Whoops404’ component.
  4. history={browserHistory} is the part to resolve with the query string in the URL.

Here’s little nice gotcha for those using Node’s Express server and receiving this cute little error.

OH NO????
  1. You weren’t pay attention in class.
  2. Now you realized why people write the following line before their Express ‘Error’ middleware.
I was the guy not paying attention in class…shame =(

This line ensures the server handles all GET requests by serving the index.html file.

Clueless One: “But why would we want the server to serve, or re-serve, the same index.html file over and over again?”
Wiser One: “Because young grasshopper, the index.html file contains your client-side application”
Clueless One: ……….???
Wiser One: “If the backend (Express) gives up all GET requests handling to the front-end (React Router), then the router may route to its heart’s content”

In conclusion, I hope this article helps clarify and prevent another soul from losing three+ hours of their life with React Router@1.0.0.

Any feedback is appreciated, but please spare me comments regarding grammar or misspellings.

Chulander Outz!