Navegacion con React JS

En esta entrada os quiero contar como podéis realizar una simple navegación en react js. Tendremos en cuenta objetivos como:

  • Mostrar menú importado desde un file.json
  • Estructura JSX para el contenido
  • Estructura de las página a mostrar internas y externas
  • Aplicar clase active
  • librería de iconos
  • Estilos de css en línea y externo

Veremos todos estos pasos uno a uno y en el orden que hemos indicado.

1.Mostrar menú importado desde un file.json

En un fichero .json tendremos los elementos de nuestro menú con todas las características necesarias que queramos visualizar, veamos el código:

[
   {
      "id":1,
      "name":"login",
      "alias":"login",
      "icon":"fa fa-key",
      "url":"/"
   },
   {
      "id":2,
      "name":"Home",
      "alias":"home",
      "icon":"fa fa-home",
      "url":"/home/"
   },
   {
      "id":3,
      "name":"Dashboard",
      "alias":"dashboard",
      "icon":"fa fa-tag",
      "url":"/dashboard/"
   }
]

En este código podemos ver como el fichero json con el que vamos a trabajar tiene tres elementos principales con diferentes características como el id, nombre, alias, icono, ruta … Para poder trabajar con el fichero debemos importarlo en nuestro proyecto de la siguiente forma

import Menu from './data/menu.json';

Una vez importado ya podemos hacer uso de ello ahora vamos a recorrer el fichero para poder listar los elementos de menú.

class Showmenu extends Component{
    render() {
      return (
        <ul className="menu">
          {
            Menu.map( li=>{
              return(
              <li key={li.id}   >
                <NavLink data-alias={li.alias} to={li.url}   >
                  <span>{li.name}</span>
                </NavLink>
              </li>
              )
            })
          }
        </ul>
      )
  }
}

Usamos la función .map() para el tomar array que nos llegará a través del import del fichero.json.

2. Estructura JSX para el contenido

En el código anterior vemos como hemos incluido elementos de jsx necesarios para listar el menú.

Actualmente este es el resultado y código de nuestro proyecto.

import React, {Component} from 'react';
import { BrowserRouter, Switch, Route, NavLink, Redirect } from 'react-router-dom';
import Menu from './data/menu.json';


class Showmenu extends Component{
    render() {
      return (
        <ul className="menu">
          {
            Menu.map( li=>{
              return(
              <li key={li.id}   >
                <NavLink data-alias={li.alias} to={li.url}   >
                  <span>{li.name}</span>
                </NavLink>
              </li>
              )
            })
          }
        </ul>
      )
  }
}

function App() {
  return (
    <div className="App">
      <BrowserRouter>
          <div className="header">
                <Showmenu></Showmenu> 
          </div>
        </div>
      </BrowserRouter>
    </div>
  );
}

export default App;

Mostramos a través de una lista el contenido del fichero json. La estructura del menú la tenemos guardada en una clase llamada Showmenú la cual estamos llamando en la función principal que va mostrar todo el contenido de nuestro proyecto.

A continuación veremos también la estructura necesaria para completar el proceso de navegación que será el resultado que se visualice en los diferentes enlaces del menú

3.Estructura de las página a mostrar internas y externas

Para poder mostrar dicho resultado crearemos diferentes funciones, cada una de ellas contiene el resultado a mostrar cuando se selecciona esa opción, este sería el código.

function Login() {
  return <h2>Login</h2>;
}
function Home() {
  return <h2>Home</h2>;
}

function Dashboard() {
  return <h2>Dashboard</h2>;
}

Dentro de cada función introduciremos el código que consideremos necesario, puede ser tan extenso como queráis eso si recordar devolverlo en un único elemento para no tener error de código.

Actualmente la visualización de nuestro proyecto sigue siendo la misma, ya que aunque a pesar de tener la estructura para listar el menú y el contenido de cada sección no lo estamos vinculando. Para poder realizar esa vinculación cambiaremos la estructura de nuestra función principal App().

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <div>
          <div className="header">
            
          <Showmenu></Showmenu> 
         
          </div>
          <div className="content">
            <Switch>
              <Route path="/" component={Login} />
              <Route path="/home/" component={Home} />
              <Route path="/dashboard/" component={Dashboard} />
            </Switch>
          </div>
        </div>
      </BrowserRouter>
    </div>
  );
}

El uso de elementos como BrowserRouter, Switch , Route … son necesarios para el proceso de navegación y se declaran arriba del todo de nuestro fichero , nuevamente os dejo el código completo y la vista de nuestro proyecto actualmente así podéis ver la declaración de dichos elementos.

import React, {Component} from 'react';
import { BrowserRouter, Switch, Route, NavLink, Redirect } from 'react-router-dom';
import Menu from './data/menu.json';


function Login() {
  return <h2>Login</h2>;
}
function Home() {
  return <h2>Home</h2>;
}

function Dashboard() {
  return <h2>Dashboard</h2>;
}

class Showmenu extends Component{
    render() {
      return (
        <ul className="menu">
          {
            Menu.map( li=>{
              return(
              <li key={li.id}   >
                <NavLink data-alias={li.alias} to={li.url}   >
                  <span>{li.name}</span>
                </NavLink>
              </li>
              )
            })
          }
        </ul>
      )
  }
}

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <div>
          <div className="header">
            
          <Showmenu></Showmenu> 
         
          </div>
          <div className="content">
            <Switch>
              <Route path="/" component={Login} />
              <Route path="/home/" component={Home} />
              <Route path="/dashboard/" component={Dashboard} />
            </Switch>
          </div>
        </div>
      </BrowserRouter>
    </div>
  );
}
export default App;

Como podéis comprobar actualmente tendríamos el proceso de navegación funcionando pero si no queremos mezclar en el mismo fichero unas estructuras con otras podríamos tener el contenido de la navegación en ficheros a parte.

Veamos un ejemplo, para ello crearemos el fichero home.js que contendrá la información a mostrar en esa opción.

import React from 'react';

function Home() {
  return (
    <div>
      Pagina de home externa
    </div>
  );
}

export default Home;

Lo incluiremos arriba en nuestro proyecto con el resto del elementos que hemos incluido anteriormente

import Home from './content/examples/Home';

Esta es otra forma de contener estructura jsx en diferentes ficheros. Es una opción más limpia ya que podemos tener tanto ficheros como necesitemos y cada uno de ellos recogerá su información correspondiente.

Ahora mismo se podría decir que tenemos nuestra navegación funcionando y en ficheros a parte, pero vamos a ver más cosas para completar este menú, como la funcionalidad de marcar como active el enlace del menú que estamos visualizando.

4.Aplicar clase active

Para poder destacar el enlace de menú que estamos visitando actualmente, usaremos la propiedad exact que es un booleano que nos ayudará ya que sirve para definir si la ruta será exacta o no.

Esta propiedad la colocaremos en dos lugares en los elementos navlink del menu y en los route que crean la vinculación. Si ambas son exactas pintaremos la clase active, veamos el ejemplo del código para dejarlo más claro.

<NavLink exact  data-alias={li.alias} to={li.url} activeClassName="active" >
         <span>{li.name}</span>
 </NavLink>
 <Switch>
     <Route exact path="/" component={Login} />
     <Route path="/home/" component={Home} />
     <Route path="/dashboard/" component={Dashboard} />
</Switch>

Si abrimos la consola de nuestro navegador y seleccionamos cualquier opción de menú veremos que la opción seleccionada contiene la clase active, para que todo esto quede más claro os ánimo a leer este artículo , el cual me ayudó a entender mejor los elementos de la navegación.

Continuemos completando el menú, para ello veremos como añadir iconos a los enlaces.

5. Librería de iconos

La librería de iconos que usaremos será font-awesome, si lo conocéis podéis visitar también este enlace.

Para poder dar uso de la librería en nuestro proyecto debemos importarla, os dejo otro enlace de un artículo que escribí y trata sobre esto mismo.

Nuevamente os dejo el código completo para que podáis tener todo lo que hemos ido viendo.


import React, {Component} from 'react';
import { BrowserRouter, Switch, Route, NavLink, Redirect } from 'react-router-dom';

import '../node_modules/font-awesome/css/font-awesome.min.css'; 


import Menu from './data/menu.json';
import Home from './content/examples/Home';


// Páginas internas

function Login() {
  return <h2>Login</h2>;
}


function Dashboard() {
  return <h2>Dashboard</h2>;
}

class Showmenu extends Component{
  render() {
    return (
      <ul className="menu">
         
          {
            Menu.map( li=>{
              return(
              <li key={li.id}   >
                <NavLink exact  data-alias={li.alias} to={li.url}  activeClassName="active" >
                  <i className={li.icon}></i>
                  <span>{li.name}</span>
                </NavLink>
              </li>
              )
            })
          }
        </ul>
    )
  }
}

function App() {

  return (
    <div className="App">
      <BrowserRouter>
        <div>
          <div className="header">
            
          <Showmenu></Showmenu> 
         
          </div>
          <div className="content">
            <Switch>
              <Route exact path="/" component={Login} />
              <Route path="/home/" component={Home} />
              <Route path="/dashboard/" component={Dashboard} />
            </Switch>
          </div>
        </div>
      </BrowserRouter>
    </div>
  );
}

export default App;
import React from 'react';

function Home() {
  return (
    <div>
      Pagina de home externa
    </div>
  );
}

export default Home;

Para completar nuestro tutorial sólo queda dar estilos al menú.

6. Estilos de css en línea y externo

Podemos dar los estilos en línea o de una forma más limpia importando un fichero .css externo, veamos ambas:

CSS en línea: Para ello crearemos unas constantes dentro del render que contendrá el css que queremos añadir en línea a cada elemento. Es un poco engorroso porque tenemos crear constantes diferente para cada elemento. Aquí os dejo algunos ejemplos.

     const styleUl = {
        display: "flex",
        padding: "10px",
        'flex-wrap':'wrap',
        'justify-content':'space-around',
        fontFamily: "Arial",
        'border-bottom':'1px solid #ddd'
      };
      const styleLi = {
        'list-style':'none',
      };

      const styleA = {
        display: "inline-block",
        'text-decoration':'none',
        padding:'8px',
        'border-radius':'4px',
        color: "white",
        backgroundColor: "DodgerBlue",
        fontFamily: "Arial"
      };

      

Para usar esos estilos sólo necesitamos indicar que elemento llevará esas constantes

 <ul  style={styleUl}>
         
          {
            Menu.map( li=>{
              return(
              <li key={li.id}  style={styleLi} >
                <NavLink exact style={styleA} data-alias={li.alias} to={li.url}  activeClassName="active" >
                  <i className={li.icon}></i>
                  <span>{li.name}</span>
                </NavLink>
              </li>
              )
            })
          }
        </ul>

Si nos fijamos en el código , hemos añadido esas contantes a los elementos ul, li , NavLink. Como comentamos anteriormente también es posible hacerlo de forma externa.

CSS externo: Sólo necesitamos importar el fichero con el contenido css arriba del todo en el fichero principal del proyecto y añadir esas clases o estilos a los elementos con los que estamos trabajando.

import styles from './css/style.css'; 

Hemos llegado al final del tutorial, ha sido un poco extenso pero espero que os haya servido de ayuda. a continuación os dejo el código completo con todo lo que hemos ido viendo.

Fichero App.js


import React, {Component} from 'react';
import { BrowserRouter, Switch, Route, NavLink, Redirect } from 'react-router-dom';

import '../node_modules/font-awesome/css/font-awesome.min.css'; 
import styles from './css/style.css'; 

import Menu from './data/menu.json';
import Home from './content/examples/Home';


// Páginas internas

function Login() {
  return <h2>Login</h2>;
}


function Dashboard() {
  return <h2>Dashboard</h2>;
}

class Showmenu extends Component{
  render() {

    return (
      <ul className="menu" >
         
          {
            Menu.map( li=>{
              return(
              <li key={li.id}   >
                <NavLink exact  data-alias={li.alias} to={li.url}  activeClassName="active" >
                  <i className={li.icon}></i>
                  <span>{li.name}</span>
                </NavLink>
              </li>
              )
            })
          }
        </ul>
    )
  }
}

function App() {

  return (
    <div className="App">
      <BrowserRouter>
        <div>
          <div className="header">
            
          <Showmenu></Showmenu> 
         
          </div>
          <div className="content">
            <Switch>
              <Route exact path="/" component={Login} />
              <Route path="/home/" component={Home} />
              <Route path="/dashboard/" component={Dashboard} />
            </Switch>
          </div>
        </div>
      </BrowserRouter>
    </div>
  );
}

export default App;

Fichero Home.js

import React from 'react';

function Home() {
  return (
    <div>
      Pagina de home externa
    </div>
  );
}

export default Home;

Fichero style.css

.menu{
    display: flex;
    padding: 10px;
    flex-wrap:wrap;
    justify-content:space-around;
    font-Family: "Arial";
    border-bottom:1px solid #ddd;
}
    .menu li{
        list-style: none;
    }
        .menu li a{
            display: inline-block;
            text-decoration:none;
            padding:8px;
            border-radius:4px;
            color: white;
            background-Color: DodgerBlue;
            font-Family: "Arial";
        }
        .menu li a.active{
            background-color: #ff1ed8;
        }
            .menu li a i{
                display: inline-block;
                margin-right: 5px;
            }

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *