No tienes acceso a esta clase

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

Componente Navbar

5/31
Recursos

Aportes 48

Preguntas 8

Ordenar por:

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

Para tener un c贸digo m谩s limpio y que luego sea mas f谩cil su mantenimiento y evoluci贸n yo hice lo siguiente:

// Cree un componente llamado NavItem que acepta las propiedades to, children y activeStyle
const NavItem = ({ to, children, activeStyle }) => {
  return (
    // Use la etiqueta NavLink y le pas茅 las propiedades to y className
    <NavLink
      to={to}
      className={({ isActive }) => (isActive ? activeStyle : undefined)}
    >
      {children}
    </NavLink>
  );
};

Y luego:

	 <li>
          <NavItem to="/clothes" activeStyle={activeStyle}>
            Clothes
          </NavItem>
        </li>
        <li>
          <NavItem to="/electronics" activeStyle={activeStyle}>
            Electronics
          </NavItem>
        </li>
        <li>
          <NavItem to="/fornitures" activeStyle={activeStyle}>
            Fornitures
          </NavItem>
        </li>
        <li>
          <NavItem to="/toys" activeStyle={activeStyle}>
            Toys
          </NavItem>
        </li>
        <li>
          <NavItem to="/others" activeStyle={activeStyle}>
            Others
          </NavItem>
        </li>

Ya vimos en el video la forma imperativa:
Les muestro una variante de forma mas declarativa:

1)Creamos 2 constantes que contengan un array con un objeto con las diferentes propiedades que gustemos

let menu1 = [
    {
        to: '/',
        text: 'Shopi',
        className: 'font-semibold text-lg'
    },
    {
        to: '/',
        text: 'All',
        className: ''
    },
    {
        to: '/clothes',
        text: 'clothes',
        className: ''
    },
    {
        to: '/electronics',
        text: 'electronics',
        className: ''
    },
    {
        to: '/furnitures',
        text: 'furnitures',
        className: ''
    },
    {
        to: '/toys',
        text: 'toys',
        className: ''
    },
    {
        to: '/others',
        text: 'others',
        className: ''
    },
]

let menu2 = [
    {
        to: '/email',
        text: '[email protected]',
        className: 'text-black/60'
    },
    {
        to: '/myorders',
        text: 'My orders',
        className: ''
    },
    {
        to: '/myoccount',
        text: 'My occount',
        className: ''
    },
    {
        to: '/signin',
        text: 'Sign in',
        className: ''
    },
    {
        to: '/shoppcar',
        text: '馃洅',
        className: ''
    },
]

2)Recorremos y renderizamos con map el componente link.

const NavBar = () => {
    const textDecoration = 'underline underline-offset-4'

  return (
    <nav className="flex items-center justify-between w-full py-5 px-8 text-sm">
        <ul className='flex gap-3 items-center'>
            {menu1.map(link => (
                <li 
                    key={link.text}
                    className={link.className}
                >
                    <NavLink 
                        to={link.to}
                        className={({isActive})=> isActive ? textDecoration : undefined }
                    >
                        {link.text}
                    </NavLink>
                </li>
            ))}
        </ul>
        <ul className='flex gap-3 items-center'>
            {menu2.map(link => (
                <li 
                    key={link.text}
                    className={link.className}
                >
                    <NavLink 
                        to={link.to}
                        className={({isActive})=> isActive ? textDecoration : undefined }
                    >
                        {link.text}
                    </NavLink>
                </li>
            ))}
        </ul>
    </nav>
  )
}

Si utilizaron arreglos para abstraer la informacion de cada NavLink para su componente. Se van a dar cuenta que el primer y segundo elemento se subrayan, ya que ambos tienen la misma direccion. Una solucion para este problema es agregar una nueva condicion al classname del componente Navlink.

Con esta solucion el elemento Shopi no se va a subrayar.
El arreglo del menu se ve de la siguiente forma:

Los emoji salen oprimiendo la tecla windows y el punto al mismo tiempo !!!

Diferencias entre componentes: De react-router-dom
1)NavLink: Nos brinda un callback/funcion con un objeto con las propiedades: isActive y Pending. util para saber cuando un elemento esta activo o pendiente. su manera de uso popular es en los menu de navegacion, sin necesidad de recargar la pagina.

2)Link: No nos brinda nada y direcciona directamente a la ruta sin necesidad de recargar la pagina.

Hola comunidad les comparto unos peque帽os apuntes en Notion, espero les sean de utilidad.
Link aqu铆:
https://bg99astro.notion.site/Componente-Navbar-4e186ba4bcac4ec38a15e48dc1dc666f?pvs=4

Mi resultado

Repeto el uso de TailwindCSS, creo que ayuda a muchos. Pero particularmente no me gusta como se vuleve un reguero de propiedades quitando la legibilidad de codigo de quien desarrolla!

A partir del curso anterior de React, quiz谩 esto pueda ser m谩s escalable.

  1. Cree un componente NavItem:
function NavItem ({ className, to, activeStyle, navbarName }) {
  return (
    <li className={(className)}>
      <NavLink
        to={to}
        className={
          ({ isActive }) => (isActive ? activeStyle : undefined)
        }
      >
        {navbarName}
      </NavLink>
    </li>
  )
}

  1. En el componente index.jsx, creamos un objeto con las siguientes propiedades:
const navItems = [
  { name: 'Shopi', to: '/', className: 'font-semibold text-xl' },
  { name: 'All', to: '/' },
  { name: 'Clothes', to: '/clothes' },
  { name: 'Electronics', to: '/electronics' },
  { name: 'Furnitures', to: '/furnitures' },
  { name: 'Toys', to: '/toys' },
  { name: 'Others', to: '/others' }
]
  1. Recorremos:
function Navbar () {
  const activeStyle = 'underline'

  return (
    <nav className='flex items-center'>
      <ul className='flex items-center gap-3'>
        {
          navItems.map(({ to, className, name }) => (
            <NavItem
              key={name}
              to={to}
              className={className}
              navbarName={name}
              activeStyle={activeStyle}
            />
          ))
        }
      </ul>
    </nav>
  )
}

En vez de hardcodear todos los navs cree un archivo que contenga todas las rutas (izq y der) para que sea din谩mico y con un .map se recorrer todas y pegarlas

Siii鈥 funciono en Produccion!! Chau Hashhh鈥
Genia Estefy!! Te amo鈥 me salvaste !! si no tenia que emigrar a NExT 馃槂

Si tenes problemas con vite y tailwindcss https://tailwindcss.com/docs/guides/vite muestra como instalarlo.

Comparto mi c贸digo. En lo posible trato de hacer mis patrones de dise帽o lo m谩s escalable posibles. En este caso, en vez de crear tantos NavLink, cre茅 dos constantes, que me almacenaran tanto el titulo del nav y su path. Con esto si a futuro tengo que remover o agregar alguno, solo modifico la constante y resulta m谩s c贸modo y a nivel visual tambi茅n es m谩s entendible. Lo 煤nico que dej茅 fijo y fuera de las constantes fue el correo y el carrito de compra. Que los puse textualmente ah铆: ```js import { NavLink } from "react-router-dom"; const componentsToNavRight = [ { name: 'Shopi', path: '/' }, { name: 'All', path: '/' }, { name: 'Clothes', path: '/clothes' }, { name: 'Electronics', path: '/electronics' }, { name: 'Furnitures', path: '/furnitures' }, { name: 'Toys', path: '/toys' }, { name: 'Others', path: '/others' }, ]; const componentsToNavLeft = [ { name: 'My Orders', path: '/my-orders' }, { name: 'My Account', path: '/my-account' }, { name: 'Sign In', path: '/sign-in' }, ] function Navbar() { const activeStyle = "underline underline-offset-4"; return ( <nav className='flex justify-between items-center fixed z-10 w-full py-5 px-8 text-sm font-light'>
    {componentsToNavRight.map((component, index) => (
  • <NavLink to={component.path} className={({isActive}) => (isActive && index !==0) ? activeStyle : ''}> {component.name} </NavLink>
  • ))}
  • [email protected]
  • {componentsToNavLeft.map((component, index) => (
  • <NavLink to={component.path} key={index}> {component.name} </NavLink>
  • ))}
  • Carrito de compra
</nav> ); } export { Navbar }; ```

Los filtros (ej: all, clothes), al ser menos complejos, los refactorice con un array para hacer m谩s corto el NavBar:

const filtersRoutes = [
    "all",
    "clothes",
    "electronics",
    "furnitures",
    "toys",
    "others",
  ];

return (
	{filtersRoutes.map((route) => (
     	<li key={route}>
            <NavLink
              to={`/${route}`}
              className={({ isActive }) => (isActive ? activeStyle : undefined)}>
              {route.charAt(0).toUpperCase() + route.slice(1)}
            </NavLink>
      </li>
  ))}
)

Como aporte adicional al comentario de Alba Cecilia, ac谩 tengo un ejemplo del mismo c贸digo pero hecho con Typescript.

const activeStyle = "underline underline-offset-4";

const NavLinkStyled: FC<{
  to: string;
  children: ReactNode;
  isLogo?: boolean;
}> = ({ children, to, isLogo }) => (
  <NavLink
    className={({ isActive }) =>
      isActive && !isLogo ? activeStyle : undefined
    }
    to={to}
  >
    {children}
  </NavLink>
);

La 煤nica diferencia es que mand茅 el estilo de activeStyle fuera de los componentes para no andarlo pasando como prop y adicional mand茅 una validaci贸n para no mostrar el underline en el logo.

asi quedaria con next 13 en un componente cliente, yo itero recorriendo un objeto rutas, pero tambien se puede cambiar para que las reciba como props.

Para tenerlo a la mano

//
const activeStyle = 'underline underline-offset-4'

// estilos para Nav Link
<NavLink 
	to = '/'
	className = {({  isActive  })  =>
		isActive  ?  activeStyle :  undefined
	}>
	All
</NavLink>

Genial que React-Router tenga de por si una propiedad
styles para el elemento NavLink
no lo tenia presente, sin duda uno aprende cosas nuevas,

Una solucion para los que no les dejo el underline: `let activeStyle = { ` `borderBottom: "1px solid black",` `paddingBottom: "2px", };`
Cree el componente *NavLinkStyled* para no repetir los estilos y adem谩s la funci贸n *renderNavLinks* para iterar el array con la informaci贸n. Separ茅 los arrays en una carpeta data, tambi茅n se podr铆a separar el componente *NavLinkStyled* en otro archivo dentro de la carpeta componentes. ```js import { NavLink } from "react-router-dom"; import { NAVLINKS_HOME, NAVLINKS_PLATFORM } from "../../data/navigations"; const Navbar = () => { const activeStyle = "underline underline-offset-4"; const NavLinkStyled = ({ to, text }: { to: string; text: string }) => ( <NavLink to={to} className={({ isActive }) => (isActive ? activeStyle : undefined)} > {text} </NavLink> ); const renderNavLinks = (linkArr: { to: string; text: string }[]) => { return ( <> {linkArr.map(({ to, text }) => (
  • <NavLinkStyled to={to} text={text} />
  • ))} ); }; return ( <nav className="flex justify-between items-end fixed z-10 w-full py-5 px-8 text-sm font-light">
    • <NavLink to={"/"}>Shopi</NavLink>
    • {renderNavLinks(NAVLINKS_HOME)}
    </nav> ); }; export default Navbar; ``` ```js export const NAVLINKS_HOME = [ { to: "/", text: "All", }, { to: "/clothes", text: "Clothes", }, { to: "/electronics", text: "Electronics", }, { to: "/furnitures", text: "Furnitures", }, { to: "/toys", text: "Toys", }, { to: "/others", text: "Others", }, ]; export const NAVLINKS_PLATFORM = [ { to: "/my-account", text: "My account", }, { to: "/my-order", text: "My order", }, { to: "/my-orders", text: "My orders", }, { to: "/sign-in", text: "Sign in", }, ]; ```
    Cree el componente *NavLinkStyled* para no repetir los estilos y adem谩s la funci贸n *renderNavLinks* para iterar el array con la informaci贸n. Separ茅 los arrays en una carpeta data, tambi茅n se podr铆a separar el componente *NavLinkStyled* en otro archivo dentro de la carpeta componentes. ```js import { NavLink } from "react-router-dom"; import { NAVLINKS_HOME, NAVLINKS_PLATFORM } from "../../data/navigations"; const Navbar = () => { const activeStyle = "underline underline-offset-4"; const NavLinkStyled = ({ to, text }: { to: string; text: string }) => ( <NavLink to={to} className={({ isActive }) => (isActive ? activeStyle : undefined)} > {text} </NavLink> ); const renderNavLinks = (linkArr: { to: string; text: string }[]) => { return ( <> {linkArr.map(({ to, text }) => (
  • <NavLinkStyled to={to} text={text} />
  • ))} ); }; return ( <nav className="flex justify-between items-end fixed z-10 w-full py-5 px-8 text-sm font-light">
    • <NavLink to={"/"}>Shopi</NavLink>
    • {renderNavLinks(NAVLINKS_HOME)}
    </nav> ); }; export default Navbar; ```聽export const NAVLINKS\_HOME = \[聽 聽 {聽 聽 聽 to: "/",聽 聽 聽 text: "All",聽 聽 },聽 聽 {聽 聽 聽 to: "/clothes",聽 聽 聽 text: "Clothes",聽 聽 },聽 聽 {聽 聽 聽 to: "/electronics",聽 聽 聽 text: "Electronics",聽 聽 },聽 聽 {聽 聽 聽 to: "/furnitures",聽 聽 聽 text: "Furnitures",聽 聽 },聽 聽 {聽 聽 聽 to: "/toys",聽 聽 聽 text: "Toys",聽 聽 },聽 聽 {聽 聽 聽 to: "/others",聽 聽 聽 text: "Others",聽 聽 },聽 ]; 聽 export const NAVLINKS\_PLATFORM = \[聽 聽 {聽 聽 聽 to: "/my-account",聽 聽 聽 text: "My account",聽 聽 },聽 聽 {聽 聽 聽 to: "/my-order",聽 聽 聽 text: "My order",聽 聽 },聽 聽 {聽 聽 聽 to: "/my-orders",聽 聽 聽 text: "My orders",聽 聽 },聽 聽 {聽 聽 聽 to: "/sign-in",聽 聽 聽 text: "Sign in",聽 聽 },聽 ]; ```ts export const NAVLINKS_HOME = [ { to: "/", text: "All", }, { to: "/clothes", text: "Clothes", }, { to: "/electronics", text: "Electronics", }, { to: "/furnitures", text: "Furnitures", }, { to: "/toys", text: "Toys", }, { to: "/others", text: "Others", }, ]; export const NAVLINKS_PLATFORM = [ { to: "/my-account", text: "My account", }, { to: "/my-order", text: "My order", }, { to: "/my-orders", text: "My orders", }, { to: "/sign-in", text: "Sign in", }, ]; ``` import { NavLink } *from* "react-router-dom";import { NAVLINKS\_HOME, NAVLINKS\_PLATFORM } *from* "../../data/navigations"; const Navbar = () => {聽 const activeStyle = "underline underline-offset-4"; 聽 const NavLinkStyled = ({ to, text }: { to: string; text: string }) => (聽 聽 \<NavLink聽 聽 聽 *to*={to}聽 聽 聽 *className*={({ isActive }) => (isActive ? activeStyle : undefined)}聽 聽 >聽 聽 聽 {text}聽 聽 \</NavLink>聽 ); 聽 const renderNavLinks = (linkArr: { to: string; text: string }\[]) => {聽 聽 return (聽 聽 聽 <>聽 聽 聽 聽 {linkArr.map(({ to, text }) => (聽 聽 聽 聽 聽 \
  • 聽 聽 聽 聽 聽 聽 \<NavLinkStyled *to*={to} *text*={text} />聽 聽 聽 聽 聽 \
  • 聽 聽 聽 聽 ))}聽 聽 聽 \聽 聽 );聽 }; 聽 return (聽 聽 \<nav *className*="flex justify-between items-end fixed z-10 w-full py-5 px-8 text-sm font-light">聽 聽 聽 \
      聽 聽 聽 聽 \
    • 聽 聽 聽 聽 聽 \<NavLink *to*={"/"}>Shopi\</NavLink>聽 聽 聽 聽 \
    • 聽 聽 聽 聽 {renderNavLinks(NAVLINKS\_HOME)}聽 聽 聽 \
    聽 聽 聽 \
      聽 聽 聽 聽 \
    • [email protected]\
    • 聽 聽 聽 聽 {renderNavLinks(NAVLINKS\_PLATFORM)}聽 聽 聽 聽 \
    • 馃洅 0\
    • 聽 聽 聽 \
    聽 聽 \</nav>聽 );}; export default Navbar;
    Optimizando: *import* { NavLink } *from* 'react-router-dom'; const categories = \['All', 'Clothes', 'Electronics', 'Furniture', 'Toys', 'Others'];const userLinks = \['My Orders', 'My Account', 'Sign In']; const navLinks = (*items*) => {聽 const activeStyle = ({ *isActive* }) => (*isActive* ? 'underline underline-offset-4' : '');聽 *return* *items*.map((*item*, *index*) => {聽 聽 const path = *item* === 'All' ? '/' : `/${*item*.toLowerCase().replace(/*\s*/*g*, '-')}`;聽 聽 const label = *item*;聽 聽 *return* (聽 聽 聽 \
  • 聽 聽 聽 聽 \<NavLink *to*={path} *className*={activeStyle}>聽 聽 聽 聽 聽 {label}聽 聽 聽 聽 \</NavLink>聽 聽 聽 \
  • 聽 聽 );聽 });}; const NavbarX = () => {聽 *return* (聽 聽 \<nav *className*="fixed z-10 flex justify-between items-center gap w-full py-5 px-8 font-light text-sm border">聽 聽 聽 \
      聽 聽 聽 聽 \<NavLink *to*="/" *className*="mr-8 font-bold text-base">聽 聽 聽 聽 聽 Shopi聽 聽 聽 聽 \</NavLink>聽 聽 聽 聽 {navLinks(categories)}聽 聽 聽 \
    聽 聽 聽 \
      聽 聽 聽 聽 \
    • [email protected]\
    • 聽 聽 聽 聽 {navLinks(userLinks)}聽 聽 聽 聽 \
    • 馃洅2\
    • 聽 聽 聽 \
    聽 聽 \</nav>聽 );}; *export* *default* NavbarX; ```jsx import { NavLink } from 'react-router-dom'; const categories = ['All', 'Clothes', 'Electronics', 'Furniture', 'Toys', 'Others']; const userLinks = ['My Orders', 'My Account', 'Sign In']; const navLinks = (items) => { const activeStyle = ({ isActive }) => (isActive ? 'underline underline-offset-4' : ''); return items.map((item, index) => { const path = item === 'All' ? '/' : `/${item.toLowerCase().replace(/\s/g, '-')}`; const label = item; return (
  • <NavLink to={path} className={activeStyle}> {label} </NavLink>
  • ); }); }; const NavbarX = () => { return ( <nav className="fixed z-10 flex justify-between items-center gap w-full py-5 px-8 font-light text-sm border">
      <NavLink to="/" className="mr-8 font-bold text-base"> Shopi </NavLink> {navLinks(categories)}
    </nav> ); }; export default Navbar; ```
    **Un hack** por si no lo sab铆an, en VScode le das a crear archivo y escribes ejem:` Navbar/index.jsx` Autom谩ticamente, te crea la carpeta y dentro el archivo y as铆 no tienes que presionar: crear carpeta y luego crear archivo
    ![](https://static.platzi.com/media/user_upload/image-903e556a-13ea-4e4a-866c-6f7fa41369f6.jpg)```js import { NavLink } from "react-router-dom" const Navbar = () => { return ( <nav className="flex justify-between p-6 border-b border-green-300">
    • <NavLink to='/All'> All </NavLink>
    • <NavLink to='/Machos'> Machos </NavLink>
    • <NavLink to='/Hembras'> Hembras </NavLink>
    </nav> ) } export default Navbar ```El mio lo hice pensando en una pagina de adopciones
    Hola, yo puse los links aparte para tenerlo m谩s ordenado: ```js const linksNavBar = [ { label: 'Shopi', route: '/', symbol: '' }, { label: 'All', route: '/', symbol: '' }, { label: 'Clothes', route: '/clothes', condition: '/clothes', symbol: '' }, { label: 'Electronics', route: '/electronics', symbol: '' }, { label: 'Furnitures', route: '/furnitures', symbol: '' }, { label: 'Toys', route: '/toys', symbol: '' }, { label: 'Others', route: '/others', symbol: '' } ] ``````js
      {linksNavBar.map((data) => <NavLinkIcons data={data} key={data.label} />)}
    ```
    Tomando como ejemplo la forma declarativa que postearon antes hice mi propia versi贸n, le puse renderizado condicional porque no todos los li son de navegaci贸n, y tambi茅n separ茅 la funcion del className del NavLink ya que se me hace muy repetitiva ```js const Navbar = () => { const activeStyle = 'underline underline-offset-4' const leftnav = [ { to: '/', text: 'Shope', className: 'font-semibold text-lg' }, { to: '/', text: 'All', className: '' }, { to: '/clothes', text: 'Clothes', className: '' }, { to: '/electronics', text: 'Electronics', className: '' }, { to: '/furniture', text: 'Furniture', className: '' }, { to: '/toys', text: 'Toys', className: '' }, { to: '/others', text: 'Others', className: '' }, ] const rightnav = [ { to: undefined, text: '[email protected]', className: 'text-black/60' }, { to: '/my-orders', text: 'my-orders', className: '' }, { to: '/my-account', text: 'my-account', className: '' }, { to: '/sign-in', text: 'sign-in', className: '' }, { to: undefined, text: '馃洅 0', className: '' }, ] const NavLinkClass = (isActive) => (isActive ? activeStyle : undefined) return ( <nav className='flex justify-between items-center fixed z-10 w-full py-5 px-8 text-sm font-light'>
      {leftnav.map(({ to, text, className }) => { return (
    • <NavLink to={to} className={text === 'Shope' ? '' : ({ isActive }) => NavLinkClass(isActive)}> {text} </NavLink>
    • ) })}
      {rightnav.map(({ to, text, className }) => { return (
    • {to ? ( <NavLink to={to} className={({ isActive }) => NavLinkClass(isActive)}> {text} </NavLink> ) : ( <>{text} )}
    • ) })}
    </nav> ) } export default Navbar ```const Navbar = () => {聽 const activeStyle = 'underline underline-offset-4' 聽 const leftnav = \[聽 聽 { to: '/', text: 'Shope', className: 'font-semibold text-lg' },聽 聽 { to: '/', text: 'All', className: '' },聽 聽 { to: '/clothes', text: 'Clothes', className: '' },聽 聽 { to: '/electronics', text: 'Electronics', className: '' },聽 聽 { to: '/furniture', text: 'Furniture', className: '' },聽 聽 { to: '/toys', text: 'Toys', className: '' },聽 聽 { to: '/others', text: 'Others', className: '' },聽 ] 聽 const rightnav = \[聽 聽 { to: undefined, text: '[email protected]', className: 'text-black/60' },聽 聽 { to: '/my-orders', text: 'my-orders', className: '' },聽 聽 { to: '/my-account', text: 'my-account', className: '' },聽 聽 { to: '/sign-in', text: 'sign-in', className: '' },聽 聽 { to: undefined, text: '馃洅 0', className: '' },聽 ] 聽 const NavLinkClass = (*isActive*) => (*isActive* ? activeStyle : undefined) 聽 return (聽 聽 \<nav className='flex justify-between items-center fixed z-10 w-full py-5 px-8 text-sm font-light'>聽 聽 聽 \
      聽 聽 聽 聽 {leftnav.map(({ *to*, *text*, *className* }) => {聽 聽 聽 聽 聽 return (聽 聽 聽 聽 聽 聽 \
    • 聽 聽 聽 聽 聽 聽 聽 \<NavLink to={*to*} className={*text* === 'Shope' ? '' : ({ *isActive* }) => NavLinkClass(*isActive*)}>聽 聽 聽 聽 聽 聽 聽 聽 {*text*}聽 聽 聽 聽 聽 聽 聽 \</NavLink>聽 聽 聽 聽 聽 聽 \
    • 聽 聽 聽 聽 聽 )聽 聽 聽 聽 })}聽 聽 聽 \
    聽 聽 聽 \
      聽 聽 聽 聽 {rightnav.map(({ *to*, *text*, *className* }) => {聽 聽 聽 聽 聽 return (聽 聽 聽 聽 聽 聽 \
    • 聽 聽 聽 聽 聽 聽 聽 {*to* ? (聽 聽 聽 聽 聽 聽 聽 聽 \<NavLink to={*to*} className={({ *isActive* }) => NavLinkClass(*isActive*)}>聽 聽 聽 聽 聽 聽 聽 聽 聽 {*text*}聽 聽 聽 聽 聽 聽 聽 聽 \</NavLink>聽 聽 聽 聽 聽 聽 聽 ) : (聽 聽 聽 聽 聽 聽 聽 聽 <>{*text*}\聽 聽 聽 聽 聽 聽 聽 )}聽 聽 聽 聽 聽 聽 \
    • 聽 聽 聽 聽 聽 )聽 聽 聽 聽 })}聽 聽 聽 \
    聽 聽 \</nav>聽 )}export default Navbar
    TS: ![](https://static.platzi.com/media/user_upload/carbon%20%281%29-973c5b9b-4d1a-46ee-96f4-221f0fa7fa3c.jpg)
    ```ts //archivo de rutas export const navRoutes = [ { path: '/', name: 'Shopi', }, { path: '/', name: 'All', }, { path: '/clothes', name: 'Clothes', }, { path: '/electronics', name: 'Electronics', }, { path: '/furnitures', name: 'Furnitures', }, { path: '/toys', name: 'Toys', }, { path: '/others', name: 'Others', }, { path: '/my-orders', name: 'My Orders', }, { path: '/my-account', name: 'My Account', }, { path: '/sign-in', name: 'Sign In', }, ]; ``` ```js // componente navbar import { IoCartOutline } from 'react-icons/io5'; import { NavLink } from 'react-router-dom'; import { navRoutes } from '../routes/nav.routes'; export const NavBar = () => { return ( <nav className="flex justify-between items-center fixed w-full px-8 py-5 text-sm font-light">
    • {navRoutes .map(({ name, path }, index) => ( <NavLink key={name} to={path} className={({ isActive }) => isActive && index !== 0 ? 'underline underline-offset-4 transition-all' : `${index === 0 ? 'font-semibold text-lg' : ''}` } > {name} </NavLink> )) .slice(0, 7)}
    • [email protected]
    • {navRoutes .map(({ name, path }) => ( <NavLink key={name} to={path}> {name} </NavLink> )) .slice(7, 10)}
    • <IoCartOutline />
    </nav> ); }; ```fue lo que se me ocurri贸 para no tener 2 arreglos de rutas por separado. 鉁岋笍

    Teilwind me parece de lo m谩s horrible que existe el c贸digo se ve s煤per sucio y desordenado, pero bueno, me lo tendr茅 que aprender. 馃槥

    Pueden ahorrarse un poco de codigo poniendo el className del NavLink dentro de una const de la siguiente manera:

    Creamos la constante encima del return

     const handleActive = ({ isActive }) => isActive ? activeStyle : undefined
    

    A cada <NavLink> le agregan la funcion

    <li>
                        <NavLink
                            to='/'
                            className={handleActive}
                        >
                            All
                        </NavLink>
                    </li>
    

    Asi se veria el codigo completo

    import { NavLink } from "react-router-dom"
    
    const Navbar = () => {
    
        const activeStyle = 'underline underline-offset-4'
    
        const handleActive = ({ isActive }) => isActive ? activeStyle : undefined
    
    
        return (
            <nav className="flex justify-between items-center fixed z-10 w-full py-5 px-8 font-light">
                <ul className="flex items-center gap-3">
                    <li className="font-semibold text-lg">
                        <NavLink
                            to='/'
    
                        >
                            Shopi
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/'
                            className={handleActive}
                        >
                            All
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/clothes'
                            className={handleActive}
                        >
                            Clothes
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/electronics'
                            className={handleActive}
                        >
                            Electronics
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/furnitures'
                            className={handleActive}
                        >
                            Furnitures
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/toys'
                            className={handleActive}
                        >
                            Toys
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/others'
                            className={handleActive}
                        >
                            Others
                        </NavLink>
                    </li>
                </ul>
    
                <ul className="flex items-center gap-3">
                    <li className="text-black/60">
                        [email protected]
                    </li>
                    <li>
                        <NavLink
                            to='/my-orders'
                            className={handleActive}
                        >
                            My Orders
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/my-account'
                            className={handleActive}
                        >
                            My Account
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/sign-in'
                            className={handleActive}
                        >
                            Sign in
                        </NavLink>
                    </li>
                    <li>
                        <NavLink
                            to='/No-Lo-He-Hecho'
                            className={handleActive}
                        >
                            馃洅 0
                        </NavLink>
                    </li>
    
                </ul>
            </nav>
        )
    }
    
    export default Navbar
    

    Tef, mucha calidad, me encanta

    Mi soluci贸n

    import { NavLink } from "react-router-dom";
    
    function Navbar() {
      const activeStyle = "underline underline-offset-4";
    
      return (
        <nav className="flex justify-between items-center fixed z-10 top-0 w-full py-5 px-8 text-sm font-light">
          
          <ul className="flex items-center gap-3">
            <li className="font-semibold text-lg">
              <NavLink to="/">Shopi</NavLink>
            </li>
            {routesLeft.map((route) => (
              <li key={route.to}>
                <NavLink
                  to={route.to}
                  className={({ isActive }) => (isActive ? activeStyle : undefined)}
                >
                  {route.label}
                </NavLink>
              </li>
            ))}
          </ul>
    
          <ul className="flex items-center gap-3">
            <li className="text-black/60">[email protected]</li>
            {routesRight.map((route) => (
              <li key={route.to}>
                <NavLink
                  to={route.to}
                  className={({ isActive }) => (isActive ? activeStyle : undefined)}
                >
                  {route.label}
                </NavLink>
              </li>
            ))}
            <li>馃洅 0</li>
          </ul>
          
        </nav>
      );
    }
    
    const routesLeft = [];
    routesLeft.push({ to: "/", label: "All" });
    routesLeft.push({ to: "/clothes", label: "Clothes" });
    routesLeft.push({ to: "/electronics", label: "Electronics" });
    routesLeft.push({ to: "/furnitures", label: "Furnitures" });
    routesLeft.push({ to: "/toys", label: "Toys" });
    routesLeft.push({ to: "/others", label: "Others" });
    
    const routesRight = [];
    routesRight.push({ to: "/my-orders", label: "My Orders" });
    routesRight.push({ to: "/my-account", label: "My Account" });
    routesRight.push({ to: "/sing-in", label: "Sign In" });
    
    
    export { Navbar };
    

    Para que nos salga la ayuda de las clases de Tailwind CSS en VSCode solo debemos instalar la extension oficial de Tailwind CSS.

    para hacer nuestro Navbar mobile-first simplemente podemos agregar estas lineas de c贸digo

    flex flex-col sm:flex-row text-sm sm:text-lg
    

    Otra forma de separar el estilo del los elementos visualmente:

    const activeStyle = ({ isActive }) => isActive && "underline underline-offset-4";
    
    <NavLink className={activeStyle} to={"/"}>
    	Shopi
    </NavLink>
    

    mi componente <Navbar/> tratando de no repetir mucho el codigo y creando un componente aparte para los items de Navbar

    En vista de que la fakeAPI de Platzi tiene errores, use la Fake Store por lo que tuve que traer sus categorias de la siguiente manera

    const API = "https://fakestoreapi.com/products/categories";
    
    const menus = ["my-orders", "my-account", "sign-in" ];
    
    const activeStyle = "underline underline-offset-4";
    
    const isActive = ({ isActive }) => (isActive ? activeStyle : undefined);
    
    const Item = (object) => {
        return (
          <li key={object}>
            <NavLink to={`/${object}`} className={isActive}>
              {object}
            </NavLink>
          </li>
        );
    };
    

    Luego use esos metodos para renderizar las categorias

    // **************************COMPONENT**************************
    const NavBar = () => {
      const [categories, setCategories] = useState();
    
      useEffect(() => {
        fetch(API)
          .then(res => res.json())
          .then(data => setCategories(data))
      },[]);
    
      return (
        <nav className="flex justify-between items-center fixed z-10 top-0 w-full py-5 px-8 text-sm font-light">
          <ul className="flex items-center gap-3">
            <li className="font-semibold text-lg">
              <NavLink to="/">Shopi</NavLink>
            </li>
    
            {categories?.map(category => Item(category))}
    
          </ul>
    
          <ul className="flex items-center gap-3">
            <li className="text-black/60">[email protected]</li>
    
            {menus.map((menu) => Item(menu))};
    
            <li>馃洅0</li>
          </ul>
        </nav>
      );
    };

    Primero cree objetos con las categorias y menus

    const categories = [
      { name: "All", link: "/" },
      { name: "Clothes", link: "/clothes" },
      { name: "Electronics", link: "/electronics" },
      { name: "Furnitures", link: "/furnitures" },
      { name: "Toys", link: "/toys" },
      { name: "Others", link: "/others" },
    ];
    
    const menus = [
      {name: "My Orders", link: "/my-orders"},
      {name: "My Account", link: "/my-account"},
      {name: "Sign In", link: "/sign-in"}
    ];
    

    Luego cree dos funciones, una para el isActive y otra para crear los items del navbar

    const activeStyle = "underline underline-offset-4";
    
    const isActive = ({ isActive }) => isActive ? activeStyle : undefined; 
    
    const Item = (object) => {
      return (
        <li key={object.name}>
          <NavLink
            to={object.link}
            className={isActive}
          >
            {object.name}
          </NavLink>
        </li>
      );
    };
    

    Luego renderizo el navbar haciendo map a los objetos y agregandolos al DOM con la funcion Item

    const NavBar = () => {
      return (
        <nav className="flex justify-between items-center fixed z-10 w-full py-5 px-8 text-sm font-light">
          <ul className="flex items-center gap-3">
            <li className="font-semibold text-lg">
              <NavLink to="/">Shopi</NavLink>
            </li>
    
            {categories.map((category) => (
              Item(category)
            ))};
    
          </ul>
    
          <ul className="flex items-center gap-3">
            <li className="text-black/60">[email protected]</li>
            
            {menus.map((menu) => (
              Item(menu)
            ))};
    
            <li>馃洅0</li>
          </ul>
        </nav>
      );
    };
    

    Este en mi archivo de NavBar

    import React from 'react'
    import {NavLink} from 'react-router-dom'
    
    const navLinksLeft = [
        { to: '/', text: 'All' },
        { to: '/clothes', text: 'Clothes' },
        { to: '/electronics', text: 'Electronics' },
        { to: '/furniture', text: 'Furniture' },
        { to: '/toys', text: 'Toys' },
        { to: '/others', text: 'Others' },
    ]
    
    const navLinksRight = [
        { to: '/my-orders', text: 'My orders' },
        { to: '/my-account', text: 'My account' },
        { to: '/sign-in', text: 'Sign in' },
    ]
    
    function NavBar() {
    
        const activeStyle = 'underline underline-offset-4'
    
        return (
            <>
            <nav className='flex justify-between items-center fixed z-10 w-full py-5 px-8 text-sm font-light'>
                <ul className='flex items-center gap-3'>
                    <li className='font-semibold text-lg'>
                        <NavLink to='/'>
                            Shopii
                        </NavLink>
                    </li> 
    
                    {navLinksLeft.map((link) => (
                        <li key={link.to}>
                            <NavLink 
                                to={link.to}
                                className={({ isActive }) => isActive ? activeStyle : 'undefined'}
                            >
                                {link.text}
                            </NavLink>
                        </li>
                    ))}
    
                </ul>
                <ul className='flex items-center gap-3'>
    
                    <li className='text-black/60'>
                        [email protected]
                    </li>
    
                    {navLinksRight.map((link) => (
                        <li key={link.to}>
                            <NavLink 
                                to={link.to}
                                className={({ isActive }) => isActive ? activeStyle : 'undefined'}
                            >
                                {link.text}
                            </NavLink>
                        </li>
                    ))}
    
                    <li>
                        C
                    </li>
                </ul>
            </nav>
            </>
        )
    } 
    
    export { NavBar }
    

    Me parece que de esta forma es menos codigo y espcialmente es m谩s facil mantenerlo porque puedes modificar en un solo lugar (al hacer el .map) y cambiar a todos los elementos

    Lo 煤nico loco que se me ocurri贸 para no repetir tanto code fu茅:
    crear esta constante

    const classlink = ({isActive}) => isActive ? activeStyle : undefined;
    

    y ponerla en sus respectivas classes:

    <li>
    	<NavLink to='/'
                  className = {classlink}>
                        All
            </NavLink>
    </li>
    

    Hoy estoy de poca inspiraci贸n xD!

    Yo utilize map y clsx que es una peque帽a utilidad (228B) para construir cadenas className condicionalmente.
    Tambi茅n sirve como un reemplazo directo m谩s r谩pido y m谩s peque帽o para el m贸dulo de nombres de clase.
    https://www.npmjs.com/package/clsx
    Navbar.jsx

    import { NavLink } from "react-router-dom";
    import { menu1, menu2 } from "../data/menu";
    import clsx from "clsx";
    
    export const Navbar = () => {
      return (
        <nav className="flex items-center justify-between sticky z-10 w-full py-4 px-8 text-sm">
          <ul className="flex items-center gap-3">
            <li className="font-semibold text-lg">
              <NavLink to="/">Shopi</NavLink>
            </li>
            {menu1.map((list) => (
              <li key={list.id}>
                <NavLink
                  to={list.to}
                  className={({ isActive }) =>
                    clsx(
                      "px-3 border",
                      isActive
                        ? "transition duration-500 rounded-xl border-green-400"
                        : "border-transparent"
                    )
                  }
                >
                  {list.link}
                </NavLink>
              </li>
            ))}
          </ul>
    
          <ul className="flex items-center gap-3">
            <li className="text-black/60">
              <NavLink to="/">[email protected]</NavLink>
            </li>
            {menu2.map((list) => (
              <li key={list.id}>
                <NavLink
                  to={list.to}
                  className={({ isActive }) =>
                    clsx(
                      "px-3 border",
                      isActive
                        ? "transition duration-500 rounded-xl border-green-400"
                        : "border-transparent"
                    )
                  }
                >
                  {list.link}
                </NavLink>
              </li>
            ))}
          </ul>
        </nav>
      );
    };
    
    

    En una carpeta aparte llamada data cree el array del menu para poder iterar:

    export const menu1 = [
      {
        id: 1,
        link: "All",
        to: "/",
      },
      {
        id: 2,
        link: "Clothes",
        to: "/clothes",
      },
      {
        id: 3,
        link: "Electronics",
        to: "/electronics",
      },
      {
        id: 4,
        link: "Furniture",
        to: "/furniture",
      },
      {
        id: 5,
        link: "Toys",
        to: "/toys",
      },
      {
        id: 6,
        link: "Others",
        to: "/others",
      },
    ];
    
    export const menu2 = [
      {
        id: 1,
        link: "My orders",
        to: "/my-orders",
      },
      {
        id: 2,
        link: "My Account",
        to: "/my-account",
      },
      {
        id: 3,
        link: "Sign in",
        to: "/sign-in",
      },
      {
        id: 4,
        link: "馃洅0",
        to: "/shopp-car",
      },
    ];
    
    

    Para usar Navlink, se debe importar previamente desde react router dom

    猸 Dos estudiantes hiceron aportes interesantisimos sobre como podemos mostrar los elementos del [navbar] y darles el estilo de 鈥渦nderline鈥

    Combine ambos aportes y este fue el resultado:

    https://github.com/mt-alejo/pj-ecommerce-react/blob/main/src/Components/Navbar/index.jsx

    Me encanto, gracias!

    hasta aqu铆, ya voy aprendiendo algunas cosas nuevas. Gracias Teff

    Excelente video estoy aprendiendo una parte importante que no sabia Gracias Estefany 馃槂 馃榿馃槑

    Mi c贸digo hasta ahora, utilizando el m茅todo map y first child en tailwind:

    import { NavLink } from "react-router-dom";
    
    const Navbar = () => {
      const activeStyle = "underline underline-offset-4";
    
      const categories = [
        { to: "/", text: "Home" },
        { to: "/all", text: "All" },
        { to: "/clothes", text: "Clothes" },
        { to: "/furniture", text: "Furniture" },
        { to: "/toys", text: "Toys" },
      ];
    
      const routes = [
        { to: "/my-orders", text: "My Orders" },
        { to: "/my-account", text: "My Account" },
        { to: "/sign-in", text: "Sign In" },
      ];
      return (
        <nav className="flex justify-between items-center fixed z-10 w-full py-5 px-8 text-sm font-light">
          <ul className="flex items-center gap-3">
            {categories.map((category, index) => (
              <li key={index} className="first:font-semibold first:text-lg">
                <NavLink
                  to={category.to}
                  className={({ isActive }) => ` ${isActive ? activeStyle : ""}`}
                >
                  {category.text}
                </NavLink>
              </li>
            ))}
          </ul>
          <ul className="flex items-center gap-3">
            <li className="text-black/60">[email protected]</li>
            {routes.map((route, index) => (
              <li key={index}>
                <NavLink
                  to={route.to}
                  className={({ isActive }) => ` ${isActive ? activeStyle : ""}`}
                >
                  {route.text}
                </NavLink>
              </li>
            ))}
            <li>馃洅2</li>
          </ul>
        </nav>
      );
    };
    
    export default Navbar;
    
    

    Descarguen la extensi贸n para tailwind que sugiere la profa.

    Tailwind