Paso a paso

Empezando con React Router v4

Vamos a jugar con la nueva versión de React Router v4. A diferencia de la versión anterior, las rutas funcionan como componentes reales de React, lo cual es un enorme logro ya que simplifica mucho el manejo de rutas en nuestras aplicaciones React.

A lo largo de este artículo crearemos una aplicación de usuarios con detalle y repasaremos algunos conceptos para tener lista nuestra app. Manos a la obra.

Primero la instalación

React Router se ha dividido en tres paquetes: react-routerreact-router-dom y react-router-native.
Casi nunca tendrás que instalar react-router directamente pues este paquete proporciona los principales componentes y funciones de enrutamiento para las aplicaciones React Router. Los otros dos proporcionan componentes específicos del entorno (web y mobile).
Debes elegir el paquete correcto para el entorno de tu aplicación, en nuestro caso utilizaremos react-router-dom ya que es una aplicación web.

npm install --save react-router-dom

¿Qué Router?

Al iniciar cada proyecto debemos determinar qué tipo de router utilizaremos.
Para aplicaciones web tenemos los componentes de <BrowserRouter> y <HashRouter>. El componente <BrowserRouter> es más utilizado en servidores que manejan peticiones dinámicas, mientras que <HashRouter> se utiliza en sitios web estáticos. Yo prefiero utilizar <BrowserRouter>, aunque si tu servidor web solo sirve archivos estáticos <HashRouter> es una buena solución. Para nuestra aplicación, utilizaremos<BrowserRouter>.

Renderizando <Router>

El componente del router recibe un solo elemento secundario. Para trabajar dentro de esta limitación, es útil crear un componente <App> que procese el resto de la aplicación.

import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router } from "react-router-dom";
import App from "./Components/App";
render(
  <Router>
    <App />
  </Router>,
document.getElementById("root"));

Ahora que ya tenemos nuestro router podemos comenzar a escribir nuestra aplicación.

La <App>

Nuestra aplicación está definida por un componente <App> y para simplificar nuestra aplicación la dividiremos en dos componentes: el <Header>, que se encargará de manejar nuestros enlaces, y el <Main>, que será el componente donde se renderizará el resto de nuestro contenido.

import React from "react";
import Main from "./Main";
import Header from "./Header";
const App = () => (
  <div>
    <Header />
    <Main />
  </div>
);
export default App;

<Header>

Nuestro <Header> es el componente encargado de renderizar nuestros enlaces, para ello React Router nos provee de un componente llamado<Link>, el cual es el encargado de solicitar la ruta indicada y renderizar el contenido sin la necesidad de recargar el sitio.

import React from "react";
import { Link } from "react-router-dom";
const Header = () => (
  <Header>
    <nav>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/users">Users</Link></li>
        <li><Link to="/about">About</Link></li>
      </ul>
    </nav>
  </Header>
);
export default Header;

<Main>

Nuestro componente <Main> será el encargado de renderizar nuestro contenido, para ello utilizaremos <Switch> y <Route> de React Router. Creamos las rutas y cada ruta renderizará un componente según sea el path solicitado.

import React from "react";
import { Switch, Route } from "react-router-dom";
import Home from "./Home";
import Users from "./Users";
import About from "./About";
const Main = () => (
  <Main>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/users" component={Users} />
      <Route path="/about" component={About} />
    </Switch>
  </Main>
);
export default Main;

<Home> <About> <Users>

Ahora toca el momento de crear los componentes que se verán en cada una de nuestras rutas. <Home> y <About> son componentes estáticos. <Users> es un componente dinámico que se encargará de renderizar un listado de usuarios y un perfil para cada uno de esos usuarios según sea solicitado por los enlaces.

import React from "react";
import { Switch, Route } from "react-router-dom";
import AllUsers from "./AllUsers";
import Profile from "./Profile";
const Home = () => (
  <h1>Mi aplicación con React Router v4!</h1>
);
const About = () => (
  <div>
    <h1>Daniel Venegas</h1>
    <p>Sr. Front End Developer, adicto al anime, cine y series,     
       jugador de fifa y amante del whisky
    </p>
  </div>
);
const Users = ({ match }) => (
  <Switch>
    <Route exact path={`${match.url}`} component={AllUsers} />
    <Route path={`${match.url}/:id`} component={Profile} />
  </Switch>
);

<AllUsers>

Este componente es el encargado de mostrar un listado de usuarios, asignándoles un nuevo enlace compuesto por la ruta actual más su ID.

import React from "react";
import UsersAPI from "../api";
import { Link } from "react-router-dom";
const mapUser = url =>
  UsersAPI.all().map(u => (
    <li key={u.id}>
      <Link to={`${url}/${u.id}`}>{u.name}</Link>
    </li>
  ));
const AllUsers = ({ match }) => (
  <div>
    <ul>{ mapUser(match.url) }</ul>
  </div>
);
export default AllUsers;

<Profile>

Por último, tenemos que mostrar en nuestro componente el perfil de cada uno de nuestros usuarios. Aquí el ID con el cual consultamos nuestra api pasará por params y así poder traer el detalle de nuestro usuario.

import React from "react";
import UsersAPI from "../api";
import { Link } from "react-router-dom";
const Profile = ({ match: { params: { id } } }) => {
  const user = UsersAPI.get(parseInt(id));
  
  if (!user) {
    return <div>Lo sentimos, el usuario fue encontrado</div>;
  }
  return (
    <div>
      <h1>
        {user.name} (id: {user.id})
      </h1>
      <h2>Proyecto: {user.project}</h2>
      <Link to="/users">Back</Link>
    </div>
  );
};
export default Profile;

¡En vivo!

Te dejo el demo en vivo para que puedas jugar con él.