Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to React Router

Introduction to React Router

Learn to use React Router, a popular library in the React community, to manage navigation and rendering of components in React applications.

We’ll start with routing basics, then dive into React Router’s powerful features, including:

* Navigating routes
* Constructing a layout via nested routes
* Rendering index routes and links
* Styling active links
* Creating routes with parameters
* Displaying 404 routes and clean URLs
* What's new in React Router 4.

Bad4b01a177d5803f443e11fa7d55c59?s=128

Guil Hernandez

November 22, 2016
Tweet

More Decks by Guil Hernandez

Other Decks in Programming

Transcript

  1. React Router Introduction to

  2. Guil Hernandez @guilh Designer Front End Dev Teacher

  3. Guil Hernandez @guilh

  4. This Session Routing Basics Declaring and Navigating Routes Nested Routes

    Passing params and props Tips & New Features
  5. what’s Routing?

  6. Routing Matches a URL to what’s being rendered in the

    browser — it does something in response to a change in the current URL
  7. Routing in SPAs Loads and unloads content as users navigate

    the app, without reloading the page
  8. Routing in React Mounts and unmounts components while matching the

    URL with the set of components being rendered
  9. Routing Should: • Keep track of browser history • Seamlessly

    link users to specific sections of your app • Be consistent with the navigation experience of regular multi- page sites and apps
  10. Custom router class App extends Component { state = {

    route: window.location.hash }; componentDidMount() { window.addEventListener('hashchange', () => { this.setState({ route: window.location.hash.substr(1) }); }); } … } // App.js
  11. Custom router class App extends Component { … render() {

    let Child; switch (this.state.route) { case '/about': Child = About; break; case '/work' : Child = Work; break; default : Child = Home; } return ( <div> <a href="#/">Home</a> <a href="#/about">About</a> <a href="#/work">Work</a> <Child /> </div> ); } … // App.js
  12. Routing As your app grows and you add more routes,

    your routing code will also grow in complexity

  13. Example hierarchy <App> <Home/> <Plans> <Silver/> <Gold/> </Plans> <SignUp/> </App>

    <Home/> <Courses> </Courses> <Teachers/> <HTML/> <CSS/> <JS/>
  14. Hey, React Router!

  15. None
  16. None
  17. Install $ npm install --save react-router

  18. React Router • A set of components • You write

    routes using JSX • Easier to visualize how your routes are structured
  19. Three main components import { Router, Route, Link } from

    'react-router'; , Route, Link Router
  20. Router import React from 'react'; import { Router } from

    'react-router'; import Home from './components/Home'; ReactDOM.render(( <Router> </Router> ), document.getElementById('root')); // index.js
  21. Declaring a route import React from 'react'; import { Router,

    Route } from 'react-router'; import Home from './components/Home'; ReactDOM.render(( <Router> <Route path="" component={} /> </Router> ), document.getElementById('root')); // index.js <Route path="" component={} />
  22. Declaring a route import React from 'react'; import { Router,

    Route } from 'react-router'; import Home from './components/Home'; ReactDOM.render(( <Router> <Route path="" component={} /> </Router> ), document.getElementById('root')); // index.js <Route path="/" component={Home} />
  23. You'll experience the true power of React Router when working

    with multiple routes!

  24. Declaring multiple routes … import Home from './components/Home'; import Courses

    from './components/Courses'; import Teachers from './components/Teachers'; ReactDOM.render(( <Router> <Route path="/" component={Home} /> <Route path="/courses" component={Courses} /> <Route path="/teachers" component={Teachers} /> </Router> ), document.getElementById('root')); // index.js
  25. Declaring multiple routes … import Home from './components/Home'; import Courses

    from './components/Courses'; import Teachers from './components/Teachers'; ReactDOM.render(( <Router> <Route path="/" component={Home} /> <Route path="/courses" component={Courses} /> <Route path="/teachers" component={Teachers} /> </Router> ), document.getElementById('root')); // index.js
  26. URLs localhost:8080/#/?_k=xgx3js

  27. History • Listens for changes in the URL • Provides

    information about which components to render • Lets users navigate using back and forward buttons • Keeps the UI in sync with the URL
  28. URLs localhost:8080/#/teachers?_k=ut968k

  29. browserHistory Leverages the History API built into the browser displays

    clean, user-friendly URLs
  30. browserHistory import React from 'react'; import { Router, Route, browserHistory

    } from 'react-router'; … ReactDOM.render(( <Router history={browserHistory}> <Route path="/" component={Home} /> <Route path="/courses" component={Courses} /> <Route path="/teachers" component={Teachers} /> </Router> ), document.getElementById('root')); // index.js <Router history={browserHistory}> , browserHistory <Router>
  31. URLs localhost:8080/ localhost:8080/teachers localhost:8080/courses

  32. DevTools

  33. Navigating Routes

  34. Navigate with Link class App extends Component { render() {

    return ( <div> <header> <ul className="main-nav"> <li><Link to="/">Home</Link></li> <li><Link to="/teachers">Teachers</Link></li> <li><Link to="/courses">Courses</Link></li> </ul> </header> … </div> ); } } // App.js … import { Link } from 'react-router';
  35. Active link styles class App extends Component { render() {

    return ( <div> <header> <ul className="main-nav"> <li><Link to="/" activeStyle={{ color: 'blue' }}>Home</Link></li> <li><Link to="/teachers" activeStyle={{ color: 'blue' }}>Teachers</Link></li> <li><Link to="/courses" activeStyle={{ color: 'blue' }}>Courses</Link></li> </ul> </header> … </div> ); } } // App.js … import { Link } from 'react-router';
  36. Active link styles class App extends Component { render() {

    return ( <div> <header> <ul className="main-nav"> <li><Link to="/" activeClassName="active">Home</Link></li> <li><Link to="/teachers" activeClassName="active">Teachers</Link></li> <li><Link to="/courses" activeClassName="active">Courses</Link></li> </ul> </header> … </div> ); } } // App.js … import { Link } from 'react-router';
  37. Wrapper component import React from 'react'; import { Link }

    from 'react-router'; const NavLink = props => ( <Link {...props} activeClassName="active" /> ); export default NavLink; // NavLink.js
  38. Wrapper component class App extends Component { render() { return

    ( <div> <header> <ul className="main-nav"> <li><NavLink to="/">Home</NavLink></li> <li><NavLink to="/teachers">Teachers</NavLink></li> <li><NavLink to="/courses">Courses</NavLink></li> </ul> </header> … </div> ); } } // App.js import NavLink from './NavLink';
  39. Nested Routes

  40. None
  41. Nested Routes = Nested Views

  42. Component hierarchy <App> <Home/> <Plans> <Silver/> <Gold/> </Plans> <SignUp/> </App>

    <Home/> <Courses> </Courses> <Teachers/> <HTML/> <CSS/> <JS/>
  43. Nesting // index.js ReactDOM.render(( <Router history={browserHistory}> <Route component={App}> <Route path="/"

    component={Home} /> <Route path="/courses" component={Courses} /> <Route path="/teachers" component={Teachers} /> </Route> </Router> ), document.getElementById('root')); <Route component={App}> <Route path="/" component={Home} /> <Route path="/courses" component={Courses} /> <Route path="/teachers" component={Teachers} /> </Route> <Route path="/" component={Home} /> <Route path="/courses" component={Courses} /> <Route path="/teachers" component={Teachers} />
  44. Nesting // App.js class App extends Component { render() {

    return ( <div> <ul className="main-nav"> <li><NavLink to="/">Home</NavLink></li> <li><NavLink to="/teachers">Teachers</NavLink></li> <li><NavLink to="/courses">Courses</NavLink></li> </ul> s.props.children } </div> ); } } { this.props.children }
  45. Nested routes URL Component / App -> Home /teachers App

    -> Teachers /courses App -> Courses
  46. Nesting deeper // index.js ReactDOM.render(( <Router history={browserHistory}> <Route component={App}> <Route

    path="/" component={Home} /> <Route path="/courses" component={Courses} /> Route path="/teachers" component={Teachers} /> < /Route> </Router> ), document.getElementById('root')); <Route component={App}> <Route path="/" component={Home} /> <Route path="/courses" component={Courses} /> <R oute path ="/teachers" component={Teachers} /> </Route> <Route path="/" component={Home} /> <Route path="/courses" component={Courses}> <Route path="/html" component={HTML} /> <Route path="/css" component={CSS} /> <Route path="/javascript" component={JS} /> </Route> <Route path="/teachers" component={Teachers} /> <Route path="html" component={HTML} /> <Route path="css" component={CSS} /> <Route path="javascript" component={JS} />
  47. Nesting deeper URL Component /courses/html App -> Courses -> HTML

    /courses/css App -> Courses -> CSS /courses/javascript App -> Courses -> JS
  48. Passing Props

  49. When you pass props to <Route>, props can be used

    in the component rendered by that route.
  50. Passing props … ReactDOM.render(( <Router history={browserHistory}> <Route path="/" component={Home} title="Welcome

    Home!" /> <Route path="/courses" component={Courses} /> <Route path="/teachers" component={Teachers} /> </Router> ), document.getElementById('root')); // index.js
  51. Route props are available in component as this.props.route

  52. Accessing route props // Home.js class Home extends Component {

    render() { return ( <div> <h1>{ this.props.route.title }</h1> … s.pr </div> ); } } .title
  53. Passing data as props ReactDOM.render(( <Router history={browserHistory}> <Route component={App}> <Route

    path="/" component={Home} /> <Route path="/courses" component={Courses} /> Route path="/teachers" component={Teachers} />> </Router> ), document.getElementById('root')); <Route component={App}> <oute path="/" component={Home} /> <Route path="/courses" component={Courses} /> <R chers" com ponent={Teachers} /> </Route> <Route path="/" component={Home} /> <Route path="/courses" component={Courses}> <Route path="/html" component={HTML} /> <Route path="/css" component={CSS} /> </Route> … <Route path="html" component={CourseContainer} data={CourseList.HTML} /> … // index.js import CourseContainer from './CourseContainer'; import CourseList from './data';
  54. Rendering content // CourseContainer.js class CourseContainer extends Component { render()

    { let courseList = this.props.route.data; let courses = courseList.map((course) => { return <Course … > … }); return ( <div> { courses } s.pr </div> ); } }
  55. Parameters

  56. Route Matching Route Path Matched URL "/" root "/courses" ../courses

    "/teachers" ../teachers
  57. Declare routes that match anything in a URL's path, using

    special route parameters
  58. Defining parameters ReactDOM.render(( <Router history={browserHistory}> <Route component={App}> <Route path="/" component={Home}

    /> <Route path="/courses" component={Courses} /> Route path="/teachers" component={Teachers} />> </Router> ), document.getElementById('root')); <Route component={App}> <oute path="/" component={Home} /> <Route path="/courses" component={Courses} /> <R chers" com ponent={Teachers} /> </Route> <Route path="/" component={Home} /> <Route path="courses" component={Courses}> <Route path="/html" component={HTML} /> <Route path="/css" component={CSS} /> </Route> <Route path="featured/:topic/:name" component={Featured} /> <Route path="html" component={HTML} /> … // index.js … import Featured from './Featured';
  59. Route Matching Route Path Matched URL featured/:topic/:name /featured/javascript/james /featured/css/alena /featured/whatevs/whoevs

  60. You can use what's passed through parameters as data in

    your components with this.props.params
  61. Rendering params … const Featured = props => <p>{props.params.name} enjoys

    teaching {props.params.topic}!</p> export default Featured; // Featured.js
  62. Rendering params … <Link to="featured/javascript/jay">Jay Query</Link> // Teachers.js

  63. Rendering params <!-- Rendered HTML --> <p>Jay enjoys teaching JavaScript!</p>

  64. More Features & Tips!

  65. “404” error route ReactDOM.render(( <Router history={browserHistory}> <Route component={App}> <Route path="/"

    component={Home} /> <Route path="/courses" component={Courses} /> ="/teachers" component={Teachers} />> </Router> ), document.getElementById('root')); <Route component={App}> <Route path="/courses" component={Courses} /> <R chers" com={Teachers} /> </Route> <Route path="/" component={Home} /> <Route path="courses" component={Courses} /> <Route path="teachers" component={Teachers} /> <Route path="/html" component={HTML} /> <Route path="*" component={NotFound} /> // index.js … import NotFound from './NotFound';
  66. Route redirect // index.js ReactDOM.render(( <Router history={browserHistory}> <Route component={App}> <Route

    path="/" component={Home} /> <Route path="/courses" component={Courses} /> Route path="/teachers" component={Teachers} /> < /Route> </Router> ), document.getElementById('root')); <Route component={App}> <Route path="/" component={Home} /> <Route path="/courses" component={Courses} /> <R oute path ="/teachers" component={Teachers} /> </Route> <Route path="/" component={Home} /> <Route path="/courses" component={Courses}> <Route path="/html" component={HTML} /> <Route path="/css" component={CSS} /> < Route path="/javascript" component={JS} /> </Route> <Route path="/teachers" component={Teachers} /> <IndexRoute component={HTML} /> <Route path="html" component={HTML} /> <Route path="css" component={CSS} /> <Route path="javascript" component={JS} /> … import { Router, Route, browserHistory, IndexRedirect } from 'react-router'; <IndexRedirect to="html" />
  67. Route redirect Path Redirect URL "/courses" ../courses/html

  68. As you add more routes, it’s easier to work with

    routing if you move routes into their own file.
  69. Organizing routes <Router history={browserHistory}> <Route component={App}> <Route path="/" component={Home} />

    <Route path="/courses" component={Courses}> <IndexRedirect to="html" /> <Route path="html" component={HTML} /> <Route path="css" component={CSS} /> <Route path="javascript" component={JS} /> </Route> <Route path="/teachers" component={Teachers} /> <Route path="*" component={NotFound} /> </Route> </Router> const routes = ( ); export default routes; //router.js
  70. Organizing routes //index.js … import routes from './router'; ReactDOM.render( routes,

    document.getElementById('root') ); routes,
  71. React Router v4 H

  72. None
  73. None
  74. If you know React, you're going to know React Router

    v4
  75. Install $ npm install react-router@next

  76. v4 Components • BrowserRouter • Match • Link • Miss

    • Redirect
  77. Location & Match • Location: Data representing where a visitor

    is (or wants to go) in your app • Match: Turns a location into UI
  78. Declare routes from anywhere! … import App from './App'; ReactDOM.render(

    <App />, document.getElementById('root') ); // index.js
  79. BrowserRouter // App.js import { BrowserRouter } from 'react-router'; class

    App extends Component { render() { return ( <BrowserRouter> </BrowserRouter> ); } } <div> <h1>Course App</h1> <ul className="main-nav">…</ul> <div className="main-content">…</div> </div>
  80. Match a URL path to a component // App.js import

    { BrowserRouter, Match } from 'react-router'; class App extends Component { render() { return ( <BrowserRouter> </BrowserRouter> ); } } <div> <h1>Course App</h1> <ul className="main-nav">…</ul> <div className="main-content">…</div> </div> <Match />
  81. Match a URL path to a component // App.js <BrowserRouter>

    <div> … <Match pattern="" component={} /> </div> </BrowserRouter>
  82. Match a URL path to a component // App.js <BrowserRouter>

    <div> … <Match pattern="/" component={Home} /> </div> </BrowserRouter> <Match pattern="/teachers" component={Teachers} /> <Match pattern="/courses" component={Courses} />
  83. Match only if pattern matches path exactly // App.js <BrowserRouter>

    <div> … <Match exactly pattern="/" component={Home} /> </div> </BrowserRouter> <Match pattern="/teachers" component={Teachers} /> <Match pattern="/courses" component={Courses} />
  84. Nested routes // App.js … class App extends Component {

    render() { return ( <BrowserRouter> <div> <h1>Course App</h1> <ul className="main-nav">…</ul> <div className="main-content">…</div> <Match exactly pattern="/" component={Home} /> <Match pattern="/teachers" component={Teachers} /> <Match pattern="/courses" component={Courses} /> </div> </BrowserRouter> ); } }
  85. Nested routes URL Component / App -> Home /teachers App

    -> Teachers /courses App -> Courses
  86. If it’s not a Match, it's a Miss…

  87. Render a miss // App.js <BrowserRouter> <div> … </div> </BrowserRouter>

    <Match pattern="/" component={Home} /> <Match pattern="/teachers" component={Teachers} /> <Match pattern="/courses" component={Courses} /> <Miss component={NotFound} />
  88. In v4: • Still use <Link> to navigate • Pass

    URL params just like in v3.0
  89. URL params <BrowserRouter> <div> … </div> </BrowserRouter> <Match pattern="/" component={Home}

    /> <Match pattern="/teachers" component={Teachers} /> <Match pattern="/courses" component={Courses} /> <Match pattern="/featured/:topic/:name" component={Featured} /> <Miss component={NotFound} /> // App.js
  90. Passing props <Match pattern="/" render={ () => <Home title="Welcome!" />

    } /> <Match pattern="/teachers" component={Teachers} /> <Match pattern="/courses" component={Courses} /> … // App.js
  91. Passing props <Match pattern="courses/html" render={ () => <CourseContainer data={CourseList.HTML} />

    } /> <Match pattern="courses/css" render={ () => <CourseContainer data={CourseList.CSS} /> } /> <Match pattern="courses/javascript" render={ () => <CourseContainer data={CourseList.JS} /> } /> … // Courses.js
  92. Use pathname for patterns & relative links const Courses =

    ({ pathname }) => ( <div> <h1>Courses</h1> <ul> <li><Link to={`${pathname}/html`}>HTML</Link></li> <li><Link to={`${pathname}/css`}>CSS</Link></li> <li><Link to={`${pathname}/javascript`}>JavaScript</Link></li> </ul> … <Match pattern={`${pathname}/html`} render={…} /> <Match pattern={`${pathname}/css`} render={…} /> <Match pattern={`${pathname}/javascript`} render={…} /> </div> ); // Courses.js
  93. Route redirects const Courses = ({ pathname }) => (

    <div> <h1>Courses</h1> <ul>…</ul> … <Match pattern={`${pathname}/html`} render={…} /> <Match pattern={`${pathname}/css`} render={…} /> <Match pattern={`${pathname}/javascript`} render={…} /> </div> ); // Courses.js <Redirect to={`${pathname}/html`} />
  94. Route redirects Path Redirect URL "/courses" ../courses/html

  95. None
  96. Migrating to v4 • Move route configuration to your component

    render methods • Change <route> to <match> • Change path to pattern
  97. Find what works for you, your project and your team.

    Develop a style and approach and be consistent about it.
  98. Guil Hernandez @guilh Thanks!