No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripción 🔥

Aprende todo un fin de semana sin pagar una suscripción 🔥

Regístrate

Comienza en:

3D
9H
7M
23S

Link vs. NavLink

7/30
Recursos

Aportes 15

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Si te pasa como a mi que la ruta “/” está siempre activa, solo necesitas pasar como parametro al NavLink la propiedad end
Quedaría de la siguiente manera:

<NavLink 
      style={({ isActive }) => ({
         color: isActive ? "red" : "blue"
       })}
          to={route.to}
          end
	>
         {route.text}
</NavLink>

Me encuentro en la versión 6.4.0 de react-router-dom

SI LO BORRE NO PASA NADA QUE HAYA BORRADO EL CÓDIGO
yo: pero no me grite ;-;

Link vs. NavLink

Link

Estas nos ayudan a evitar el uso de las etiquetas <a> en caso de que deseemos pasar a otro contenido por medio de los NavHashes evitándonos el tener que volver a descargar el HTML nuevamente ya que cambia la URL manualmente.

// Importamos la etiqueta link
import { Link } from 'react-router-dom';

function Menu() {
  return (
    <nav>
      <ul>
        
        <li>
          {/* Si lo comparamos con las etiquetas <a> su href="" 
          vendría siendo su parámetro to="", para estas no hay 
          necesidad de colocar los hash */}
          <Link to="/">Home</Link>
        </li>

        <li>
          <Link to="/blog">Blog</Link>
        </li>

        <li>
          <Link to="/profile">Profile</Link>
        </li>

      </ul>
    </nav>
  );
}

Si lo probamos vemos que no nos está recargando la página y que nos envía y renderiza los componentes que deseamos.

NavLink

Este funciona exactamente igual que Link, incluso la propiedad to="/" también se usa en este componente, pero nos permite cierta flexibilidad, por ejemplo, cuando queramos darle una clase a nuestros componentes o estilos manuales nos permite que en nuestras propiedades className={} o style={} nos permite devolver una función.

// Importamos la etiqueta NavLink
import { Link, NavLink } from 'react-router-dom';

function Menu() {
  return (
    <nav>
      <ul>

        <li>
          <NavLink 
						to="/"
            className={() => ''}
            style={() => ({background: '#fff'})}
					>Home</NavLink>
        </li>

        <li>
          <NavLink to="/blog">Blog</NavLink>
        </li>

        <li>
          <NavLink to="/profile">Profile</NavLink>
        </li>

      </ul>
    </nav>
  );
}

Estas mismas funciones nos permite enviar un parámetro llamado isActive, el cual nos permite saber si la ruta en la que se envía este componente es en la que estamos actualmente, y dependiendo de eso podemos darle una nueva clase o cambiar los estilos.

Para que esto funcione debemos pasarle a nuestro componente la propiedad end, si no, este siempre permanecerá activo.

<NavLink 
	end // <--
  style={({isActive }) => ({
			color: isActive ? 'green' : 'red'
		})
	}
>Home</NavLink>

Si añadimos estas funciones una por una en los componentes tendremos bastante desorden, para arreglar este problema podemos crear un Array de posiciones.

const routes = [];

routes.push({
  to: '/',
  text: 'Home'
});
routes.push({
  to: '/blog',
  text: 'Blog'
});
routes.push({
  to: '/profile',
  text: 'Profile'
});

Y ahora podemos recorrer este Array en el JSX para que se añadan los componentes de manera dinámica.

function Menu() {
  return (
    <nav>
      <ul>

        {routes.map(route => (
          <li>
            <NavLink 
              to={route.to}
              end
              style={ ({ isActive }) => ({
                color: isActive ? 'green' : 'red'
              })}
            >
              {route.text}
            </NavLink>
          </li>
        ))}

      </ul>
    </nav>
  );
}

De esta forma creamos un componente una sola vez y se añadirán a nuestra <nav> de manera dinámica, así en el futuro no tenemos que estas copiando y pegando código, solamente debemos crear otro elemento dentro del Array.

En mi caso solo separé en un archivo routes.js

const routes = [
  {
    id: 1,
    to: '/',
    text: 'Home'
  },
  {
    id: 2,
    to: '/blog',
    text: 'Blog'
  },
  {
    id: 3,
    to: '/profile',
    text: 'Profile'
  }
];

export { routes };

y lo inserté dentro del Menú

import React from 'react';
import { Link, NavLink } from 'react-router-dom';
import { routes } from '../routes/routes.js';

const Menu = () => {
  return (
    <>
        <ul className='bg-slate-800 flex justify-around'>
      {routes.map(route => (
          <li key={route.id}>
            <NavLink
              className={({ isActive }) => (
                isActive ? 'text-white' : 'text-black'
            )}
              to={route.to}
            >{route.text}</NavLink>
          </li>
      ))}
      </ul>
    </>
  )
}

export { Menu };

routes.js

import { BlogPage } from './BlogPage';
import { HomePage } from './HomePage';
import { ProfilePage } from './ProfilePage';

const routes = [
    {
        path: '/',
        element: <HomePage />,
        text: 'Home'
    },
    {
        path: '/blog',
        element: <BlogPage />,
        text: 'Blog'
    },
    {
        path: '/profile',
        element: <ProfilePage />,
        text: 'Profile'
    },
]

export default routes

App.js

import {HashRouter, useRoutes} from 'react-router-dom'
import routes from './routes'

import { Menu } from './Menu';

function Router() {
  
  const elements = useRoutes(routes)
  return elements
}

function App() {
  return (
    <HashRouter>
      <Menu />
      <Router />
    </HashRouter>
  );
}

export default App;

Menu.js

import React from 'react'
import { NavLink } from 'react-router-dom'
import routes from './routes'

function Menu() {
    return (
        <nav>
            <ul>
                {routes.map(route =>(
                    <li>
                        <NavLink
                            style={({ isActive }) => ({
                                color: isActive ? 'red' : 'blue'
                            })}
                            to={route.path}
                        >
                                {route.text}
                        </NavLink>
                    </li>)
                )}
            </ul>
        </nav>
    )
}

export { Menu }

Mi notas de esta clase:

  • <a>

    • Hace una petición al servidor.
    • Tenemos que aclarar el uso del #.
  • Link:

    • No hace una petición del servidor.
    • No tenemos que aclarar el uso del #.
  • NavLink:

    • No hace una petición al servidor.
    • No tenemos que aclarar el uso del #.
    • Cuando le queremos dar una clase o estilos, nos va a permitir que le entreguemos una función que retorne un string, o las propiedades para la etiqueta “style” en un objeto, ¿Para que nos sirve esto? pues gracias a esta cualidad podemos recibir un parámetro llamado “isActive”

    isActive:

    Gracias a este parámetro vamos a poder asignar estilos especiales a la etiqueta <NavLink> cuando la ruta le corresponda.

<NavLink 
   style={({isActive})=>({
      color: isActive ? 'red' : 'blue'
      })}to="/">
Home
</NavLink>```

Hi banda. Como complemento, recuerden que cuando retornamos hijos a través de un .map (por ejemplo), cada hijo debe contar con la propiedad key o si no React se quejará.
.
En cada <li> que retornan al recorrer la lista de rutas, pueden colocarle como key el text o el indice. En mi caso le puse el text ya que es único para cada uno.
.

routes.map(route => (
            <li key={route.text}>
              <NavLink 
                style={({ isActive }) => ({ color: isActive ? 'red' : 'blue' })}
                to={route.to}
              >
                {route.text}
              </NavLink>
            </li>
          ))

NavLink tiene por defecto una clase con el nombre “active”. Pueden verlo desde el inspector de elementos del navegador.

asi se ve el inspector de elementos.

<aria-current="page" class="active" href="/#">HOME</a>

solo es agregarle el estilo en CSS y ya.
a.active{ color: red; }

Funciona igual que el ejemplo del profe JuanDC, sin necesidad de utilizar arrow function.

Les comparto esto si les daba este error:

error:03000086:digital envelope routines::initialization error
'err_ossl_evp_unsupported'

Descarguen la nueva actualización de react-router, si tienen actualizado el nodejs:

npm install [email protected]6.4

Por último, métele una buena fixeada:

npm audit fix --force
function Menu() {
  return (
    <NavContainer>
      <NavStyle>
        <h2>MY BLOG</h2>
        <ul className='links'>
          {routes.map(route => (
            <li key={route.to}>
              <NavLink
                className={({ isActive }) => isActive ? 'active' : undefined}

                to={route.to}
              >
                {route.text}
              </NavLink>
            </li>
          ))}
        </ul>
      </NavStyle>
    </NavContainer>
  )
}

const NavStyle = styled.nav`
  width: 90%;
  height: 100%;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;

  h2{
    color: white;
  }

  .links{
    display: flex;
    gap: 12px;
    li{
      font-size: 1.5rem;
      font-weight: 400;
      list-style: none;
      a{
      text-decoration: none;
      color: white;
      }
      .active{
        color: #efe5fd;
        font-size:1.8rem;
        font-weight: bold;
      }
    }
  }
  
`

const NavContainer = styled.div`
  width: 100%;
  height: 4.5rem;
  background-color: #555;
`
import React from 'react'
import { NavLink } from 'react-router-dom';

function Menu() {
  return (
    <ul>
      {routes.map(route => (
        <li>
          <NavLink
            style={({ isActive }) => ({
              color: isActive ? 'red' : 'blue',
            })}
            to={route.to}
          >
            {route.text}
          </NavLink>
        </li>
      ))}
    </ul>
  )
}

const routes = [];
routes.push({
  to: '/',
  text: 'Home'
})

routes.push({
  to: '/blog',
  text: 'Blog'
})

routes.push({
  to: '/profile',
  text: 'Profile'
})

routes.push({
  to: '/contact',
  text: 'Contact'
})
export { Menu };

Si quieren modificar algún hijo con NavLink:

          <NavLink to={route.LINK} key={route.LINK}>
            {({ isActive }) => (
              <li className= {
			isActive 
			? 'border-radius'
			: 'border-solid'
			
		}>
			home
              </li>
            )}
          </NavLink>

juan dc experto borrando codigos jaaaaaaaaaaaa

En la iteración de routes

routes.map( route => (
	<li> //key?
		//......
	</li>
) )

recordemos que React necesita un identificador único para no tener problemas en los renderizados.
.
Podríamos usar una propiedad “id” dentro de cada objeto del array routes.

routes.map( route => (
	<li key={route.id}>
		//......
	</li>
))

hay una forma mejor y mas limpia y es usando el hook de useRouter que ya viene instalado.

export function Menu() {
const routes = useRoutes(routesDeJuanDc)

return <>
{routes}
</>
}

y en App dentro del BrowserRouter va el componente <Menu/>
y routesDeJuanDc es el array de objetos con las props de cada Route