Juneikerc.com

¿Cómo crear un menú hamburguesa responsive con reactjs?

imagen destacada del post: ¿Cómo crear un menú hamburguesa responsive con reactjs?

Las cabeceras con barras de navegación estilo menu hamburguesa responsive son cada día más utilizadas a continuación crearemos un componente navbar funcional usando reactjs.

Dando por echo que ya tienes instalado reactjs empecemos a trabajar, agregamos a nuestro archivo app.js el componente Header que será el contenedor del menú.

jsx
import React from "react";
import Header from "./Header";
export default function App() {
return (
<>
<Header />
</>
);
}

Creando el componente Header.js para hacer un navbar o cabecera responsive.

Toda la lógica de nuestro menú responsive va a vivir dentro del componenter Header.js, aqí controlaremos el estado del navbar.

jsx
import React, { useState } from "react";
import { HeaderWrapper } from "./styles/Header";
import Navbar from "./Navbar";
import MenuButton from "./MenuButton";
function Header() {
const [open, setOpen] = useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<HeaderWrapper>
<h2>Logo</h2>
<Navbar open={open} />
<MenuButton open={open} handleClick={handleClick} />
</HeaderWrapper>
);
}
export default Header;

Explicación del estado de este componente:

Necesitamos saber cuando el menú va a estar abierto en su versión mobile, por eso necesitamos una variable open, támbien debemos crear una función que escuchara un evento de click que cambiara el valor de la variable open. Ahora desglosamos el código paso a paso.

  • Lo primero que debemos hacer es importar el gancho useState. directamente desde react.
  • Luego importamos los componentes HeaderWrapper, Navbar, y MenuButton. Todos son echos con styled-components.
  • Dentro de nuestro componente Header creamos un estado sencillo usando el hook useState(). Este estado será el encargado de controlar si el menú se muestra o desaparece.
jsx
const [open, setOpen] = useState(false);
  • Creamos la función handleClick que cambia el estado de la variable open al valor opuesto, es decir si es true lo cambia a false y viceversa setOpen(!open) esta función se ejecutará cada vez que hagamos click en el componente MenuButton. Determinándo si el menú esta abierto o cerrado.
  • Como prop le pasamos la variable open al componente Navbar y MenuButton
  • Al componente MenuButton también le pasamos la función handleClick para que se encargue de cambiar el estado.
jsx
const handleClick = () => {
setOpen(!open);
};

Creamos el componente HeaderWrapper en un archivo HeaderStyles

Agregamos algunos estilos que harán que la cabecera se vea un poco mejor.

jsx
import styled from "styled-components";
export const HeaderWrapper = styled.header`
height: 10vh;
display: flex;
justify-content: space-between;
align-items: center;
`;
  • Importamos styled de styled-components para poder crear nuestro elemento
  • Es una cabecera muy sencilla, le asignamos una altura y separamos sus elementos usando flexbox. Este no es un tutorial enfocado en el diseño, puedes mejorar el estilo a tu gusto.

Creando El componente Navbar para nuestro menú responsive con react

Este componente sera el contenedor de los enlaces de navegación de nuestro sitio por lo tanto es muy importante su estructura.

jsx
import React from "react";
import { NavbarWrapper } from "./styles/NavbarStyles";
function Navbar({ open }) {
return (
<NavbarWrapper open={open}>
<a href="#">Link</a>
<a href="#">Link</a>
<a href="#">Link</a>
<a href="#">Link</a>
</NavbarWrapper>
);
}
export default Navbar;
  • Importamos el contenedor NavBarWrapper que haremos con styled-components.
  • Creamos el componente Navbar recibimos la propiedad open function Navbar({ open })
  • Al elemento NavWrapper le pasamos la propiedad open que luego usaremos para mostrar el menú evaluando si es true o false
  • Por último agregamos varios enlaces ancla.

Aquí se empieza a poner lindo. Creamos nuestro archvio NavbarStyles.js

Creando el NavbarWrapper con styled components

jsx
import styled from "styled-components";
export const NavbarWrapper = styled.nav`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
background: turquoise;
position: fixed;
top: 10vh;
right: ${props => (props.open ? "0" : "-100%")};
width: 100%;
height: 90vh;
transition: right 0.3s linear;
@media only screen and (min-width: 624px) {
flex-direction: row;
position: initial;
height: auto;
justify-content: center;
background: white;
}
a {
padding: 0.5rem 0.8rem;
color: grey;
text-decoration: none;
}
`;
  • Agregamos algunas propiedades de flexbox para poner el menú en forma vertical (la versión que se mostrará en mobiles).
  • Establecemos el valor de la propiedad position en fixed para que el Nabvar siempre este fijo.
  • La propiedad top la establecemos en 10vh, por que es la misma altura del header, esto pone nuestro menú justo por debajo de la cabecera.
  • El valor de la propiedad right estará condicionada por el prop open que pasamos al componente NavbarWrapper right: ${props => (props.open ? "0" : "-100%")}; si es true el valor es 0 lo que hace que el menú se muestre, y si es false el valor es -100% esto esconderá el menú.
  • Asignamos un ancho del 100%, y una altura de 90vh para que ocupe el resto de la pantalla. También agregamos una transición que animará la propiedad right para que el menú entre a la pantalla suavemente.
  • Por último agregamos dentro de una media query algunas propiedades para que el navbar en pantallas más grandes se muestre horizontalmente y dentro del header.

Creando el componente MenuButton

Este componente será el encargado de abrir y cerrar el menú.

jsx
import React from "react";
import styled from "styled-components";
const MenuButtonWrapper = styled.button`
border: none;
box-shadow: 0px 0px 1px rgb(50, 50, 50);
margin-top: 1.3rem;
@media only screen and (min-width: 624px) {
display: none;
}
`;
function MenuButton({ open, handleClick }) {
return !open ? (
<MenuButtonWrapper onClick={handleClick}>
<svg viewBox="0 0 100 80" width="30" height="30" fill="#2962ff">
<rect width="90" height="10" />
<rect y="30" width="80" height="10" />
<rect y="60" width="70" height="10" />
</svg>
</MenuButtonWrapper>
) : (
<MenuButtonWrapper onClick={handleClick}>
<svg
className="svg-icon"
width="30"
height="30"
viewBox="0 0 20 20"
fill="#2962ff"
>
<path d="M15.898,4.045c-0.271-0.272-0.713-0.272-0.986,0l-4.71,4.711L5.493,4.045c-0.272-0.272-0.714-0.272-0.986,0s-0.272,0.714,0,0.986l4.709,4.711l-4.71,4.711c-0.272,0.271-0.272,0.713,0,0.986c0.136,0.136,0.314,0.203,0.492,0.203c0.179,0,0.357-0.067,0.493-0.203l4.711-4.711l4.71,4.711c0.137,0.136,0.314,0.203,0.494,0.203c0.178,0,0.355-0.067,0.492-0.203c0.273-0.273,0.273-0.715,0-0.986l-4.711-4.711l4.711-4.711C16.172,4.759,16.172,4.317,15.898,4.045z" />
</svg>
</MenuButtonWrapper>
);
}
export default MenuButton;
  • Creamos el componente MenuButtonWrapper con styled-components, Le asignamos algunos estilos base y una media query que hará que el botón desaparezca cuando la pantalla tenga un ancho mayor a 624px.
  • Creamos El componente MenuButton que recibe las props function MenuButton({ open, handleClick }).
  • Dentro del componente hacemos una condicional usando el operador ternario.
  • Si open es false muestra el típico icono de menú hamburguesa. Y si es true mostrará un icono de cerrar.
  • Por último a los dos botones les pasamos la función handleClick dentro del evento onClick, para que cada vez que se haga click sobre ellos cambie el valor de la variable open.

Con esto dariamos pro finalizado este ejercicio, este menu hamburguesa escrito en react es totalmente funcional, si lo vas a usar para un proyecto estoy seguro que puedes hacerlo mucho más hermoso y práctico que este ejemplo.

Demostración de nuestro menu echo con react js

Juneiker Castillo freelance web developer

Soy Juneiker Castillo, un desarrollador web frontend apasionado por la programación y la creación de sitios web modernos rápidos y escalables, en fin un friki 🤓 de javascript enamorado de react js ⚛️.

Sobre mi