No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Link vs. NavLink

7/30
Recursos

Aportes 24

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

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 };

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 鈥渟tyle鈥 en un objeto, 驴Para que nos sirve esto? pues gracias a esta cualidad podemos recibir un par谩metro llamado 鈥渋sActive鈥

    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>
          ))

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 }

NavLink tiene por defecto una clase con el nombre 鈥渁ctive鈥. 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.

No se olviden de desestructurar el isActive 馃槂
.

Estoy usando la versi贸n V6.15 de React Router DOM y as铆 implemente el c贸digo.
.
Como estamos usando routes.map() para recorrer el array donde almacenamos nuestras rutas, tuve que usar un key attribute para <li>.
.
Ademas destructurar isActive y usar la propiedad end.

MENU COMPONENT

function Menu() {
  return (
    <nav>
      <ul>
        {routes.map(route => (

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

          </li>

        ))} 
      </ul>
    </nav>
  )
}

.
ROUTES

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

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

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

Nav Link es muy bellako

Banda me funciono esto directo con el className para el css ![](https://static.platzi.com/media/user_upload/code-196b256d-63cd-4246-b966-af69da00fcb2.jpg)

Link vs. NavLink

.
Los componentes Link y NavLink nos ayudar谩n para que nuestra navegaci贸n no se transforme en nuevas peticiones al servidor para que descargue un nuevo HTML, sino que solo haga la navegaci贸n desde Javascript. Vamos a cambiar la etiqueta <a></a> con alguna de estas 2 opciones, y esto nos permite cambiar de url sin recargar la p谩gina y podamos mostrar la informaci贸n correspondiente.
.
Eventualmente, si utilizamos la forma normal de crear enlaces no va a funcionar, puesto que estamos utilizando un HashRouter.
.

<nav>
	<ul>
		<li>
			<a href="/">Home</a>
		</li>
		<li>
			<a href="/blog">Blog</a>
		</li>
		<li>
			<a href="/profile">Profile</a>
		</li>
	</ul>
</nav>

.
Si quisi茅ramos forzar su funcionamiento tendr铆amos que agregar manualmente los hashes a las rutas en la propiedad href. Sin embargo, esta etiqueta lo que hace es hacer una nueva petici贸n al servidor para que se descargue otra vez el HTML y no queremos eso.
.

<nav>
	<ul>
		<li>
			<a href="/">Home</a>
		</li>
		<li>
			<a href="/#/blog">Blog</a>
		</li>
		<li>
			<a href="/#/profile">Profile</a>
		</li>
	</ul>
</nav>

.
Vamos a utilizar la etiqueta <Link></Link> el cual funciona parecido a la etiqueta <a></a>, solo que en lugar de utilizar href utilizaremos la propiedad to.
.

function Menu() {
	return (
		<nav>
			<ul>
				<li>
					<Link to="/">Home</Link>
				</li>
				<li>
					<Link to="/blog">Blog</Link>
				</li>
				<li>
					<Link to="/profile">Profile</Link>
				</li>
			</ul>
		</nav>
	)
}

export { Menu };

.
Si navegamos esta vez no volver谩 a cargar la p谩gina, porque Link es un componente oficial de react-router-dom y sabe que tipo de router estamos utilizando. Esto significa que agrega o no el hash, dependiendo de lo que necesitemos. Incluso si estuvi茅ramos trabajando con un BrowserRouter la navegaci贸n se realiza sin recargar la p谩gina, sino que va a ser el mismo HTML y con Javascript estamos cambiando los componentes que renderizamos en una ruta u otra.
.

function Menu() {
	return (
		<nav>
			<ul>
				<li>
					<NavLink 
						style={({ isActive }) => ({
                color: isActive ? 'red' : 'blue',
              })}
	          to="/">Home</NavLink>
				</li>
				<li>
					<NavLink 
						style={({ isActive }) => ({
                color: isActive ? 'red' : 'blue',
              })}
						to="/blog">Blog</NavLink>
				</li>
				<li>
					<NavLink 
						style={({ isActive }) => ({
                color: isActive ? 'red' : 'blue',
              })}
						to="/profile">Profile</NavLink>
				</li>
			</ul>
		</nav>
	)
}

export { Menu };

.
Al utilizar NavLink se sigue utilizando to para la ruta, sin embargo este componente nos permite utilizar los componentes className y style. A trav茅z de estas propiedades, por ejemplo podemos utilizar funciones y recibir por destructuraci贸n al par谩metro isActive que nos indica si nos encontramos en esa ruta en particular o si est谩 activa, luego podemos realizar condicionales y devolver un estilo u otro dependiendo de ello.
.

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

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

export { Menu };

.
Como pudimos observar hab铆an partes de c贸digo repetido, por lo cual es conveniente crear un arreglo de rutas donde iremos insertando unos objetos con las propiedades to y text, que nos servir谩n para renderizar los items de nuestra lista de manera din谩mica mediante un map y utilizando el style una sola vez.

Bueno si te sale un error de consola es porque debes agregar una key para cada elemento de la lista, a mi me gusta trabajar como array de objetos de una vez:

<nav>
      <ul>
      {routes2.map(route => (
          <li key={route.id}>
            <NavLink
              
              style={({ isActive }) => ({
                color: isActive ? 'red' : 'blue',
              })}
              to={route.to}
              end
            >
              {route.text}
            </NavLink>
          </li>
        ))}
	</ul>
	</nav>

y el array:

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

Por si alguien le sirve el dato

C贸digo de la clase en TypeScript:
Igual que el c贸digo del profesor con la siguiente diferencia:

interface IRoute {
    id: number,
    to: string,
    text: string
}

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

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 鈥渋d鈥 dentro de cada objeto del array routes.

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

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 react-router-dom@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

Link VS. NavLink

Aunque ambos te redirigen hacia otra url, con NavLink en sus propiedades className y style te permiten recibir 2 par谩metros: isActive y isPending.

C贸digo usando Link

   <Link to="/">Home</Link>

C贸digo usando NavLink

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

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