Dev

By Carlos Santana on
Reading time: 3 minutes

ReactRouter-0fHVr.png

React, unline Angular, is a library instead of a framework, that means specific functionalities, for example, the routing or the prop types, are not part of the core of React. Instead, the routing is handled by a third-party library called React Router.

Let's re-use the same code we created in our last post Setting up ESLint using Airbnb React/JSX Style Guide to have our linter validation enabled.

The first thing we need to do is to install React Router, we can do it with this command:

npm install react-router-dom

Maybe you're confused about why we are installing react-router-dom instead of react-router directly. React Router contains all the common components of react-router-dom and react-router-native. That means that if you're using React just for web, then you should use react-router-dom, and if you are using React Native, then you need to install react-router-native. The react-router-dom package was created originally to contain version 4, and react-router was using version 3, also react-router-dom has some improvements over react-router. Some of them are:

  • Improved <Link> component (which renders an <a>).
  • Includes <BrowserRouter>, which interacts with the browser's window.history.
  • Includes <NavLink> component, which is a <Link> wrapper that knows whether it's active or not.
  • Includes <HasRouter>, which uses the hash in the URL to render the components. If you have one static page, you should use this component instead of <BrowserRouter>.

React Router implementation

First, we need to create four stateless components (About, Contact, Home and Error404) and naming them as index.jsx in their directories.

The first one is our Home component:

import React from 'react';

const Home = () => (
  <div className="Home">
    <h1>I'm Home</h1>
  </div>
);

export default Home;
File: src/components/Home/index.jsx

Then our About component: 

import React from 'react';

const About = () => (
  <div className="About">
    <h1>I'm About</h1>
  </div>
);

export default About;
File: src/components/About/index.jsx

Our Contact component:

import React from 'react';

const Contact = () => (
  <div className="Contact">
    <h1>I'm Contact</h1>
  </div>
);

export default Contact;
File: src/components/Contact/index.jsx

Finally, our Error 404 component: 

import React from 'react';

const Error404 = () => (
  <div className="Error404">
    <h1>Error 404: Page not found</h1>
  </div>
);

export default Error404;
File: src/components/Error/404.jsx

In our src/index.js file, we need to include our routes, which we are going to create in the next step. We need to import the BrowserRouter object from react-router-dom, and we can rename it as Router:

// Dependencies
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import './index.css';

// Routes
import AppRoutes from './routes';

render(
  <Router>
    <AppRoutes />
  </Router>,
  document.getElementById('root')
);
File: src/index.js

Now let's create our routes file, where we will import our components. First we need to add a route to execute our Home component when the user accesses to the main page (/).

// Dependencies
import React from 'react';
import { Route } from 'react-router-dom';

// Components
import App from './components/App';
import Home from './components/Home';

const AppRoutes = () => (
  <App>
    <Route path="/" component={Home} />
  </App>
);

export default AppRoutes;
File: src/routes.jsx

After that, we need to modify our App.jsx file to render the route components as children: 

import React, { Component } from 'react';
import { element } from 'prop-types';
import logo from '../shared/images/logo.svg';
import './App.css';

class App extends Component {
  render() {
    const { children } = this.props;

    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />

          {children}
        </header>
      </div>
    );
  }
}

App.propTypes = {
  children: element
};

export default App;
File: src/components/App.jsx

If you run the application, you will see the Home component in the main page (http://localhost:3000).

HomeLocalhost-7F83L.png

After this, we need to import our Error 404 component, to display it when the user tries to access any other route that does not exist.

// Dependencies
import React from 'react';
import { Route } from 'react-router-dom';

// Components
import App from './components/App';
import Home from './components/Home';
import Error404 from './components/Error/404';

const AppRoutes = () => (
  <App>
    <Route path="/" component={Home} />
    <Route component={Error404} />
  </App>
);

export default AppRoutes;
File: src/routes.jsx

If you run the application, you will see that is rendering both components (Home and Error 404):

HomeError404-JR7YA.png

You are probably wondering why this is happening. It's because we need to use the <Switch> component to execute just one component if it matches the path. We need to import the Switch component and then add it as a wrapper in our routes: 

// Dependencies
import React from 'react';
import { Route, Switch } from 'react-router-dom';

// Components
import App from './components/App';
import Home from './components/Home';
import Error404 from './components/Error/404';

const AppRoutes = () => (
  <App>
    <Switch>
      <Route path="/" component={Home} />
      <Route component={Error404} />
    </Switch>
  </App>
);

export default AppRoutes;
File: src/routes.jsx

If you run your application again, you will see the Home component only, but if we go to /somefakeurl, we will see that the Home component is executed as well, and this is an issue: 

FakeUrl-XjBrI.png

In order to fix this issue, we need to add the exact prop in the route that we want to match exactly. The problem is that /somefakeurl will match with our main route (/), but if we want to be very specific about the paths, we need to add the exact prop to our Home route:

<Route path="/" component={Home} exact />

Now if we go to /somefakeurl again, we will be able to see the Error404 component:

Error404-gHsZK.png

Adding more routes

As you can see it is very easy to implemement the React Router library. Now we can add more routes for our other components: About (/about) and Contact (/contact):

Only members can see all the codes
You can Login or Sign Up

File: src/routes.jsx

Going to /about:

About-SItOE.png

Then go to /contact:

Contact-zdcon.png

So far, we have learned how to create simple routes in our project, but in the next posts I'm going to show you how to include parameters to our routes, how to add nested routes, and how to navigate through our site using the <Link> component.

If you liked this post, help us continue growing join to our social media channels: Twitter, Facebook, Youtube and Slack. Also if you want to learn more about React, you can buy my React Cookbook.

avatarLeave a comment

Your comment

Only members can comment. You can Login or Sign Up