i can not react

React Router 4

June 02, 2019

This article is written by fosteman

React Router v4

Client-side routing introduced in React applications plays essential role in modern frontend development practice. Some of the advantageous sides are:

  • Search Engine Optimization is empowered with content-related splitting of application on pages
  • Metrics, Response latency, TTI are improved with JS backing
  • Browser history handling enables flawless (without refresh) re-direction to different parts of an application

Dynamic Routing

Typically, routing libraries of other frameworks like Angular, Ember, are concerned with static routing. Static Routing means that routing table is configured upfront.

React Router introduces Dynamic Routing, which processes routing table on-the-fly.

New React workflows and Use Cases are made possible with dynamically changing links and routes.

Browser specific routing component

With React Router v4, routing is not centralized anymore, instead it is merged with UI.

Nested components

No more use of {props.children}

Using React Router - DOM

Router is divided into three packages:

To build web application, react-router-dom is to be installed with: npm install --save react-router-dom

Then import into

import { BrowserRouter, HashRouter, Route, Link, NavLink } from "react-router-dom";

Components

To render <Home/>:

import {Home} from 'src/components/home.js'
...
<Route exact path="/home" component={Home} />

Inline render:

<Route path="/home" render={() => <div>Home</div>} />

Wrapping children components:

const ListItemLink = ({ to, ...rest }) => (
  <Route path={to} children={({ match }) => (
    <li className={match ? 'active' : ''}>
      <Link to={to} {...rest}/>
    </li>
  )}/>
)

<Link />

const HomeLink = () => (
    <Link to="/">Home</Link>
)

<NavLink />

<NavLink
  to="/me"
  activeStyle=
   activeClassName="selected">My Profile</NavLink>

Example implementation

First, import the necessary routing components:

import { BrowserRouter, Link, Route } from 'react-router-dom'

Create a <Header> component, holding links:

const Header = () => 
<nav>
  <ul>
    <li><Link to="/">Home</Link></li>
    <li><Link to="/me">About</Link></li>
  </ul>    
</nav>

Next, render available pages in <Container>:

Note: React will render all <Route>s, however, only matching <Route> will return it’s component, while others will return null by design.

const Container = () =>     
<div className="container">
  <Route path="/" exact component={HomePage} />
  <Route path="/me" exact component={About} />
</div>

Copy-paste our mock pages:

const Home = () => <div>This is Home Page</div>
const About = () => <div>This is About Page</div>
const NotFound = () => <div>404</div>

Finally, boot the app:

const App = () => (
  <BrowserRouter>
    <Header />
    <Container />
  </BrowserRouter>
)
render(<App />, document.getElementById('root'))

Inclusive routing in depth

React Router v4 uses inclusive routing instead of exclusive routing used in v3, thus without exact property in <Container> element, all <Route>s will be rendered, because, apparently, "/" and "/me" have the slash in common.

Reversal. Exclusive routing

Default exclusive routing used in React Router v3 and earlier versions. Without use of exact, the first matching component is rendered.

Workaround <Switch>

Exclusive routing is achieved in v4 with use of <Switch>:

import { Switch, Route } from 'react-router'    

<Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/me" component={About}/>
  <Route component={NotFound}/>
</Switch>

Browser History API

react-router provides a history object that exposes API to with with hash history in the browser.

This can be used to navigate inside React application dynamically:

history.push("/me")
history.replace("/me")

Equals to:

<Link to="/me"/>
<Redirect to="/me"/>