Top Banner
React Router React Meetup XXL - September 23, 2015 - Rob Gietema @robgietema
76

React Router: React Meetup XXL

Jan 14, 2017

Download

Internet

Rob Gietema
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: React Router: React Meetup XXL

React RouterReact Meetup XXL - September 23, 2015

- Rob Gietema @robgietema

Page 2: React Router: React Meetup XXL

Who am I?

Page 3: React Router: React Meetup XXL

What is react-router?

Page 4: React Router: React Meetup XXL

Routing url to React ComponentRoute /about to <About />Route /user/1234 to <User />Route /user/1234?message=Hi to <User />

Page 5: React Router: React Meetup XXL

Michael Jackson & Ryan Florence

Page 6: React Router: React Meetup XXL

2.002 commits53 releases

197 contributors180k downloads / month

Page 7: React Router: React Meetup XXL

What does it look like?

Page 8: React Router: React Meetup XXL

Defining routes

Page 9: React Router: React Meetup XXL

Simple exampleimport { Route } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Route name="about" handler={About} /> </Route>);

About page is available at /about

Page 10: React Router: React Meetup XXL

Using custom pathimport { 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

Page 11: React Router: React Meetup XXL

Default routeimport { Route, DefaultRoute } from 'react-router';

const routes = ( <Route handler={App} path="/"> <DefaultRoute handler={Home} /> <Route name="about" handler={About} /> </Route>);

Home is available at /

Page 12: React Router: React Meetup XXL

Not found routeimport { Route, NotFoundRoute } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Route name="about" handler={About} /> <NotFoundRoute handler={NotFound}/> </Route>);

Page 13: React Router: React Meetup XXL

Nestingimport { Route } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Route name="users" handler={Users}> <Route name="recent-users" path="recent" handler={RecentUsers} /> </Route> </Route>);

Recent users available at /users/recent

Page 14: React Router: React Meetup XXL

Paramsimport { Route } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Route name="users" handler={Users}> <Route name="user" path="/user/:userId" handler={User} /> </Route> </Route>);

User 1234 is available at /user/1234

Page 15: React Router: React Meetup XXL

Multiple paramsimport { Route } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Route name="users" handler={Users}> <Route name="user-message" path="/user/:userId/message/:messageId" handler={User} /> </Route> </Route>);

Example /users/123/message/456

Page 16: React Router: React Meetup XXL

Redirect routesimport { Route, Redirect } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Route name="about" handler={About} /> <Redirect from="company" to="about" /> </Route>);

/company will be redirected to /about

Page 17: React Router: React Meetup XXL

Redirect routes with paramsimport { Route, Redirect } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Redirect from="/user/me" to="user" params={{userId: MY_ID}} /> <Route name="user" path="/user/:userId" handler={User} /> </Route>);

Notice the order of the routes

Page 18: React Router: React Meetup XXL

Without nestingimport { Route, Redirect } from 'react-router';

const routes = [ <Route name="about" handler={About} />, <Route name="contact" handler={Contact} />];

Array of routes

Page 19: React Router: React Meetup XXL

Include external routesimport { Route, Redirect } from 'react-router';import aboutRoutes from 'about/routes';

const routes = { <Route handler={App} path="/"> <Redirect from="/user/me" to="user" params={{userId: MY_ID}} /> <Route name="user" path="/user/:userId" handler={User} /> {aboutRoutes} </Route>};

Page 20: React Router: React Meetup XXL

Running the router

Page 21: React Router: React Meetup XXL

Using hashesimport React from 'react';import Router from 'react-router';

Router.run(routes, (Handler) => { React.render(<Handler/>, document.body);});

Location will be http://localhost/#/about etc.

Page 22: React Router: React Meetup XXL

Using HTML5 Historyimport React from 'react';import Router from 'react-router';

Router.run(routes, Router.HistoryLocation, (Handler) => { React.render(<Handler/>, document.body);});

Location will be http://localhost/about etc.

Page 23: React Router: React Meetup XXL

Using Universal Renderingimport 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

Page 24: React Router: React Meetup XXL

Rendering the routes

Page 25: React Router: React Meetup XXL

App componentimport React from 'react';import { RouterHandler } from 'react-router';

class App extends React.Component { render() { return ( <div> <h1>Hello World!</h1> <RouterHandler /> </div> ); }}

Use RouterHandler to render matched route

Page 26: React Router: React Meetup XXL

Access router methods

Page 27: React Router: React Meetup XXL

ES5import 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

Page 28: React Router: React Meetup XXL

ES6import 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

Page 29: React Router: React Meetup XXL

ES7import 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

Page 30: React Router: React Meetup XXL

Available router methods

Page 31: React Router: React Meetup XXL

Getting paramsimport 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

Page 32: React Router: React Meetup XXL

Getting query paramsimport 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

Page 33: React Router: React Meetup XXL

Getting current routesimport 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

Page 34: React Router: React Meetup XXL

Fetching dataimport React from 'react';import Router from 'react-router';

Router.run(routes, (Handler, state) => { fetchData(state).then(() => { React.render(<Handler/>, document.body); });});

Page 35: React Router: React Meetup XXL

Fetching datafunction fetchData(state) { return Promise.all(state.routes.filter((route) => { return route.handler.fetchData; }).map((route) => { return route.handler.fetchData(state.params, state.query); });}

Page 36: React Router: React Meetup XXL

Fetching dataimport React from 'react';

class User extends React.Component { static fetchData(params) { return new Promise((resolve) => { MyApi.loadSomething(() => { resolve(); }); }); } ...}

Page 37: React Router: React Meetup XXL

isActive methodimport React from 'react';

class Tab extends React.Component { static contextTypes = { router: React.PropTypes.func, }

render() { const isActive = this.isActive(this.props.to); const className = isActive ? 'active' : ''; return <li className={className}><Link {...this.props} />; }}

Call with <Tab to="about">About</Tab>

Page 38: React Router: React Meetup XXL

Navigating between routes

Page 39: React Router: React Meetup XXL

Using hrefimport React from 'react';

class User extends React.Component { render() { return ( <a href="/about">About</a> ); }}

Don't use this!

Page 40: React Router: React Meetup XXL

Using Link Componentimport 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>

Page 41: React Router: React Meetup XXL

Using Link Componentimport 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

Page 42: React Router: React Meetup XXL

Using Link Componentimport 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

Page 43: React Router: React Meetup XXL

Using makeHrefimport 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> ); }}

Page 44: React Router: React Meetup XXL

Using makeHrefimport 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

Page 45: React Router: React Meetup XXL

Using transitionToimport React from 'react';

class User extends React.Component { static contextTypes = { router: React.PropTypes.func, }

onSubmit() { this.context.router.transitionTo('about'); } ...}

Will transition to /about

Page 46: React Router: React Meetup XXL

Using transitionToimport 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

Page 47: React Router: React Meetup XXL

Using transitionToimport 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

Page 48: React Router: React Meetup XXL

Using replaceWithimport 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

Page 49: React Router: React Meetup XXL

Using goBackimport 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

Page 50: React Router: React Meetup XXL

goForwardimport 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

Page 51: React Router: React Meetup XXL

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

Page 52: React Router: React Meetup XXL

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

Page 53: React Router: React Meetup XXL

Lifecycle methods

Page 54: React Router: React Meetup XXL

willTransitionToimport React from 'react';

class User extends React.Component { static willTransitionTo(transition) { if (!auth.loggedIn()) { transition.redirect('/login', {}, {'redirect' : transition.path}); } } ...}

Page 55: React Router: React Meetup XXL

willTransitionFromimport React from 'react';

class User extends React.Component { static willTransitionFrom(transition) { if (!form.validate()) { transition.abort(); } } ...}

Page 56: React Router: React Meetup XXL

Changes in 1.0

Page 57: React Router: React Meetup XXL

Handler to componentimport { Route } from 'react-router';

const routes = ( <Route handler={App} path="/"> <Route name="about" handler={About} /> </Route>);

...

const routes = ( <Route component={App} path="/"> <Route path="about" component={About} /> </Route>);

Page 58: React Router: React Meetup XXL

RouterHandler to propsclass App extends React.Component { render() { return ( <RouterHandler /> ); }}

class App extends React.Component { render() { return ( {this.props.children} ); }}

Page 59: React Router: React Meetup XXL

No more named routes<Route handler={App} path="/"> <Route name="user" path="/user/:userId" handler={User} /></Route>

...

<Route component={App} path="/"> <Route path="/user/:userId" component={User} /></Route>

Page 60: React Router: React Meetup XXL

Not found route<NotFoundRoute handler={NotFound} />

...

<Route path="*" component={NotFound} />

Catch all

Page 61: React Router: React Meetup XXL

Redirect routes<Route handler={App} path="/"> <Redirect from="/user/me" to="user" params={userId: '1234'} /> <Route name="user" path="/user/:userId" handler={User} /></Route>

...

<Route component={App} path="/"> <Redirect from="/user/me" to="/user/1234" /> <Route path="/user/:userId" component={User} /></Route>

Params in the url

Page 62: React Router: React Meetup XXL

Default route<Route handler={App} path="/"> <DefaultRoute handler={Home} /> <Route name="about" handler={About} /></Route>

...

<Route component={App} path="/"> <IndexRoute component={Home} /> <Route path="about" component={About} /></Route>

Home is available at /

Page 63: React Router: React Meetup XXL

Multiple componentsimport { Route } from 'react-router';

const routes = ( <Route component={App}> <Route path="users" components={{main: Users, sidebar: UsersSidebar}}/> </Route>);

Page 64: React Router: React Meetup XXL

Multiple componentsimport React from 'react';

class App extends React.Component { render() { return ( <div> <div className="Main"> {this.props.main} </div> <div className="Sidebar"> {this.props.sidebar} </div> </div> ); }}

Page 65: React Router: React Meetup XXL

Running the routerRouter.run(routes, (Handler) => { React.render(<Handler/>, document.body);});

...

import { history } from 'react-router/lib/HashHistory';

React.render(( <Router history={history}> {routes} </Router>), document.body);

Page 66: React Router: React Meetup XXL

History optionsimport { history } from 'react-router/lib/HashHistory';

import { history } from 'react-router/lib/BrowserHistory';

import { history } from 'react-router/lib/MemoryHistory';

Page 67: React Router: React Meetup XXL

Using makeHrefconst link = this.context.router.makeHref('user', { userId: 1234 }, { message: 'Hi'});

...

const link = this.context.router.createHref('/user/1234', { message: 'Hi'});

Params in the link

Page 68: React Router: React Meetup XXL

Link component<Link to="user" params={{userId: MY_ID}}>John Do</Link>

...

<Link to={'/users/' + MY_ID}>John Do</Link>

Params in the link

Page 69: React Router: React Meetup XXL

transitionTothis.context.router.transitionTo(pathname, params, query)this.context.router.transitionTo('user', { userId: 1234 }, { message: 'Hi' });

...

this.context.router.transitionTo(pathname, query, state)this.context.router.transitionTo('/user/1234', { message: 'Hi' });

Page 70: React Router: React Meetup XXL

willTransitionTo to onEnterclass User extends React.Component { static willTransitionTo(transition) { ... }}___

function requireAuth(nextState, transition) { ...}

const routes = ( <Route component={App} path="/"> <Route path="about" component={About} onEnter={requireAuth} /> </Route>);

Page 71: React Router: React Meetup XXL

willTransitionFrom to onLeaveclass User extends React.Component { static willTransitionFrom(transition) { ... }}___

function handler(nextState, transition) { ...}

const routes = ( <Route component={App} path="/"> <Route path="about" component={About} onLeave={handler} /> </Route>);

Page 72: React Router: React Meetup XXL

routerWillLeaveclass User extends React.Component { static willTransitionFrom(transition) { ... } ...}

class User extends React.Component { static routerWillLeave(nextState, router) { ... } ...}

Page 73: React Router: React Meetup XXL

Statestatic contextTypes = { router: React.PropTypes.func,}

render() { const user = this.context.router.getCurrentParams().userId;}___

static contextTypes: { location: React.Proptypes.object}

render() { const user = this.context.params.userId;}

Page 74: React Router: React Meetup XXL

State on routing componentclass User extends React.Component { render() { const location = this.props.location; const params = this.props.params; const history = this.props.history; ... }}

Page 75: React Router: React Meetup XXL

State0.x 1.x

getPath() location.pathname +location.query

getPathname() location.pathname

getParams() params

getQuery() location.query

getRoutes() routes

isActive(to, params,query)

history.isActive(pathname,query)

Page 76: React Router: React Meetup XXL

Questions?slideshare.net/robgietema