React Router is the most widely used router for React, in use by almost half of all React projects. This talk is about using React Router in your project. It will start with the basics and will go through all features React Router has to offer in the current version and the upcoming 1.0 release. I will also go through some common problems including data fetching and authentication.
9. Simple example
import { Route } from 'react-router';
const routes = (
<Route handler={App} path="/">
<Route name="about" handler={About} />
</Route>
);
About page is available at /about
10. Using custom path
import { Route } from 'react-router';
const routes = (
<Route handler={App} path="/">
<Route name="about" path="my-about" handler={About} />
</Route>
);
About page is available at /my-about
11. Default route
import { Route, DefaultRoute } from 'react-router';
const routes = (
<Route handler={App} path="/">
<DefaultRoute handler={Home} />
<Route name="about" handler={About} />
</Route>
);
Home is available at /
12. Not found route
import { Route, NotFoundRoute } from 'react-router';
const routes = (
<Route handler={App} path="/">
<Route name="about" handler={About} />
<NotFoundRoute handler={NotFound}/>
</Route>
);
21. Using hashes
import React from 'react';
import Router from 'react-router';
Router.run(routes, (Handler) => {
React.render(<Handler/>, document.body);
});
Location will be http://localhost/#/aboutetc.
22. Using HTML5 History
import React from 'react';
import Router from 'react-router';
Router.run(routes, Router.HistoryLocation, (Handler) => {
React.render(<Handler/>, document.body);
});
Location will be http://localhost/aboutetc.
23. Using Universal Rendering
import React from 'react';
import Router from 'react-router';
app.serve((req, res) => {
Router.run(routes, req.path, function (Handler) {
const html = React.renderToString(Handler);
res.send(html);
});
});
Render html to the client
27. ES5
import React from 'react';
var User = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
render: function () {
return <h1>Hello World</h1>;
}
}
Available in render self.context.router
28. ES6
import React from 'react';
class User extends React.Component {
render() {
return <h1>Hello World</h1>;
}
}
User.contextTypes = {
router: React.PropTypes.func
};
Available in render self.context.router
29. ES7
import React from 'react';
class User extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
render() {
return <h1>Hello World</h1>;
}
}
Available in render self.context.router
31. Getting params
import React from 'react';
class User extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
render() {
const user = this.context.router.getCurrentParams().userId;
return <h1>Hello user {user}</h1>;
}
}
From route /user/:userId
32. Getting query params
import React from 'react';
class User extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
render() {
const message = this.context.router.getCurrentQuery().message;
return <h1>{message}</h1>;
}
}
From url /user/1234?message=Hello%20World
33. Getting current routes
import React from 'react';
class User extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
render() {
const routes = this.context.router.getCurrentRoutes();
...
}
}
Array of routes in nesting order
34. Fetching data
import React from 'react';
import Router from 'react-router';
Router.run(routes, (Handler, state) => {
fetchData(state).then(() => {
React.render(<Handler/>, document.body);
});
});
35. Fetching data
function fetchData(state) {
return Promise.all(state.routes.filter((route) => {
return route.handler.fetchData;
}).map((route) => {
return route.handler.fetchData(state.params, state.query);
});
}
36. Fetching data
import React from 'react';
class User extends React.Component {
static fetchData(params) {
return new Promise((resolve) => {
MyApi.loadSomething(() => {
resolve();
});
});
}
...
}
39. Using href
import React from 'react';
class User extends React.Component {
render() {
return (
<a href="/about">About</a>
);
}
}
Don't use this!
40. Using Link Component
import React from 'react';
import { Link } from 'react-router';
class User extends React.Component {
render() {
return (
<Link to="about">About</Link>
);
}
}
Will generate <a href="/about">About</a>
41. Using Link Component
import React from 'react';
import { Link } from 'react-router';
class About extends React.Component {
render() {
return (
<Link to="user" params={{userId: 1234}}>User 1234</Link>
);
}
}
With params
42. Using Link Component
import React from 'react';
import { Link } from 'react-router';
class About extends React.Component {
render() {
return (
<Link to="contact" query={{message: 'Hi'}}>Say hi</Link>
);
}
}
Will generate /contact?message=Hi
43. Using makeHref
import React from 'react';
class User extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
render() {
const link = this.context.router.makeHref('about');
return (
<a href={link}>About</a>
);
}
}
44. Using makeHref
import React from 'react';
class About extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
render() {
const link = this.context.router.makeHref('user',
{ userId: 1234 },
{ message: 'Hi'});
return (
<a href={link}>About</a>
);
}
}
With params and query params
45. Using transitionTo
import React from 'react';
class User extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onSubmit() {
this.context.router.transitionTo('about');
}
...
}
Will transition to /about
46. Using transitionTo
import React from 'react';
class About extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onSubmit() {
this.context.router.transitionTo('user',
{userId: 1234});
}
...
}
Will transition to /user/1234
47. Using transitionTo
import React from 'react';
class About extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onSubmit() {
this.context.router.transitionTo('contact',
{},
{message: 'Hi'});
}
...
}
Will transition to /contact?message=Hi
48. Using replaceWith
import React from 'react';
class User extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onSubmit() {
this.context.router.replaceWith('about');
}
...
}
Not added to browser history
49. Using goBack
import React from 'react';
class About extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onClick() {
this.context.router.goBack();
}
...
}
Go back one step in history
50. goForward
import React from 'react';
class About extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onClick() {
this.context.router.goForward();
}
...
}
Go forward one step in history
51. go(n)
import React from 'react';
class About extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onClick() {
this.context.router.go(2);
}
...
}
Go forward two steps in history
52. go(-n)
import React from 'react';
class About extends React.Component {
static contextTypes = {
router: React.PropTypes.func,
}
onClick() {
this.context.router.go(-2);
}
...
}
Go backward two steps in history
65. Running the router
Router.run(routes, (Handler) => {
React.render(<Handler/>, document.body);
});
...
import { history } from 'react-router/lib/HashHistory';
React.render((
<Router history={history}>
{routes}
</Router>
), document.body);
66. History options
import { history } from 'react-router/lib/HashHistory';
import { history } from 'react-router/lib/BrowserHistory';
import { history } from 'react-router/lib/MemoryHistory';
67. Using makeHref
const link = this.context.router.makeHref('user',
{ userId: 1234 },
{ message: 'Hi'});
...
const link = this.context.router.createHref('/user/1234',
{ message: 'Hi'});
Params in the link
68. Link component
<Link to="user" params={{userId: MY_ID}}>John Do</Link>
...
<Link to={'/users/' + MY_ID}>John Do</Link>
Params in the link