¿Cómo crear una barra lateral receptiva con menú desplegable en ReactJS?

Una barra lateral es un elemento importante del diseño de un sitio web, ya que permite a los usuarios visitar rápidamente cualquier sección dentro de un sitio.

Un vistazo al proyecto: 

Requisito previo:

  1. npm
  2. crear-reaccionar-app
  3. reaccionar-enrutador-dom
  4. Ganchos useState React

Configuración básica: comenzará un nuevo proyecto usando create-react-app, así que abra su terminal y escriba:

npx create-react-app react-sidebar-dropdown

Ahora vaya a su carpeta desplegable de la barra lateral de reacción escribiendo el comando dado en la terminal:

cd react-sidebar-dropdown

Módulo requerido: Instale las dependencias requeridas en este proyecto escribiendo el comando dado en la terminal.

npm install react-router-dom
npm install --save styled-components
npm install --save react-icons

Ahora cree la carpeta de componentes en src, luego vaya a la carpeta de componentes y cree tres archivos Sidebar.js , SidebarData.js y SubMenu.js

Cree una carpeta más en src con las páginas de nombre y en las páginas cree archivos con el nombre AboutUs.js , ContactUs.js , Events.js , Services.js , Support.js .

Estructura del proyecto: La estructura de archivos en el proyecto se verá así.

Nombre de archivo: Sidebar.js: Abrir y cerrar la vista de la barra lateral, ahí es donde entra en juego el rol del gancho useState( ) .

Creamos un estado con la barra lateral del primer elemento como un estado inicial que tiene un valor falso y el segundo elemento como función setSidebar() para actualizar el estado. Luego se crea una función con el nombre showSidebar( ) que establece el valor de la barra lateral opuesto a su valor actual cada vez que se llama. 

Esta función se usa con el ícono de las barras de menú y el ícono de la cruz con la ayuda de la función onClick() . Cuando hacemos clic en el icono de las barras para ver los enlaces de sidenav, establece el valor del estado en verdadero, muestra la barra lateral y aparece un icono de cruz en lugar del icono de las barras. Cuando queremos cerrar la barra lateral, simplemente hacemos clic en el ícono de la cruz y se reemplaza con un ícono de barra después de cerrar la barra lateral porque ahora el valor del estado se establece en falso.

Javascript

import React, { useState } from "react";
import styled from "styled-components";
import { Link } from "react-router-dom";
import * as FaIcons from "react-icons/fa";
import * as AiIcons from "react-icons/ai";
import { SidebarData } from "./SidebarData";
import SubMenu from "./SubMenu";
import { IconContext } from "react-icons/lib";
  
const Nav = styled.div`
  background: #15171c;
  height: 80px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
`;
  
const NavIcon = styled(Link)`
  margin-left: 2rem;
  font-size: 2rem;
  height: 80px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
`;
  
const SidebarNav = styled.nav`
  background: #15171c;
  width: 250px;
  height: 100vh;
  display: flex;
  justify-content: center;
  position: fixed;
  top: 0;
  left: ${({ sidebar }) => (sidebar ? "0" : "-100%")};
  transition: 350ms;
  z-index: 10;
`;
  
const SidebarWrap = styled.div`
  width: 100%;
`;
  
const Sidebar = () => {
  const [sidebar, setSidebar] = useState(false);
  
  const showSidebar = () => setSidebar(!sidebar);
  
  return (
    <>
      <IconContext.Provider value={{ color: "#fff" }}>
        <Nav>
          <NavIcon to="#">
            <FaIcons.FaBars onClick={showSidebar} />
          </NavIcon>
          <h1
            style={{ textAlign: "center", 
                     marginLeft: "200px", 
                     color: "green" }}
          >
            GeeksforGeeks
          </h1>
        </Nav>
        <SidebarNav sidebar={sidebar}>
          <SidebarWrap>
            <NavIcon to="#">
              <AiIcons.AiOutlineClose onClick={showSidebar} />
            </NavIcon>
            {SidebarData.map((item, index) => {
              return <SubMenu item={item} key={index} />;
            })}
          </SidebarWrap>
        </SidebarNav>
      </IconContext.Provider>
    </>
  );
};
  
export default Sidebar;

Nombre de archivo- SidebarData.js :

Javascript

import React from "react";
import * as FaIcons from "react-icons/fa";
import * as AiIcons from "react-icons/ai";
import * as IoIcons from "react-icons/io";
import * as RiIcons from "react-icons/ri";
  
export const SidebarData = [
  {
    title: "About Us",
    path: "/about-us",
    icon: <AiIcons.AiFillHome />,
    iconClosed: <RiIcons.RiArrowDownSFill />,
    iconOpened: <RiIcons.RiArrowUpSFill />,
  
    subNav: [
      {
        title: "Our Aim",
        path: "/about-us/aim",
        icon: <IoIcons.IoIosPaper />,
      },
      {
        title: "Our Vision",
        path: "/about-us/vision",
        icon: <IoIcons.IoIosPaper />,
      },
    ],
  },
  {
    title: "Services",
    path: "/services",
    icon: <IoIcons.IoIosPaper />,
    iconClosed: <RiIcons.RiArrowDownSFill />,
    iconOpened: <RiIcons.RiArrowUpSFill />,
  
    subNav: [
      {
        title: "Service 1",
        path: "/services/services1",
        icon: <IoIcons.IoIosPaper />,
        cName: "sub-nav",
      },
      {
        title: "Service 2",
        path: "/services/services2",
        icon: <IoIcons.IoIosPaper />,
        cName: "sub-nav",
      },
      {
        title: "Service 3",
        path: "/services/services3",
        icon: <IoIcons.IoIosPaper />,
      },
    ],
  },
  {
    title: "Contact",
    path: "/contact",
    icon: <FaIcons.FaPhone />,
  },
  {
    title: "Events",
    path: "/events",
    icon: <FaIcons.FaEnvelopeOpenText />,
  
    iconClosed: <RiIcons.RiArrowDownSFill />,
    iconOpened: <RiIcons.RiArrowUpSFill />,
  
    subNav: [
      {
        title: "Event 1",
        path: "/events/events1",
        icon: <IoIcons.IoIosPaper />,
      },
      {
        title: "Event 2",
        path: "/events/events2",
        icon: <IoIcons.IoIosPaper />,
      },
    ],
  },
  {
    title: "Support",
    path: "/support",
    icon: <IoIcons.IoMdHelpCircle />,
  },
];

Filename- SubMenu.js: La lógica para los enlaces desplegables, nuevamente hecha con ganchos useState() .

Creamos un estado con el primer elemento subnav como estado inicial que tiene un valor falso y el segundo elemento como función setSubnav() para actualizar el estado. Luego se crea una función con el nombre showSubnav() que establece el valor de subnav opuesto a su valor actual cada vez que se llama.

Esta función se utiliza con el icono de abrir y el icono de cerrar. Cuando hacemos clic en el icono de abrir para ver los enlaces desplegables, establece el valor del estado en verdadero, muestra el menú desplegable y aparece un icono de cerrar en lugar del icono de abrir. Cuando queremos cerrar los enlaces desplegables, simplemente hacemos clic en el icono de cerrar y se reemplaza con un icono de abrir después de cerrar el menú desplegable porque ahora el valor del estado se establece en falso.

Como cada enlace lateral no tiene un menú desplegable, primero verifica si una línea lateral tiene una propiedad de subNav definida con ella desde la array de objetos que creamos en el archivo SidebarData.js . Si esa propiedad existe, ejecuta la lógica anterior; de lo contrario, los enlaces laterales aparecen normalmente sin ningún icono de apertura y cierre.

Javascript

import React, { useState } from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
  
const SidebarLink = styled(Link)`
  display: flex;
  color: #e1e9fc;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  list-style: none;
  height: 60px;
  text-decoration: none;
  font-size: 18px;
  
  &:hover {
    background: #252831;
    border-left: 4px solid green;
    cursor: pointer;
  }
`;
  
const SidebarLabel = styled.span`
  margin-left: 16px;
`;
  
const DropdownLink = styled(Link)`
  background: #252831;
  height: 60px;
  padding-left: 3rem;
  display: flex;
  align-items: center;
  text-decoration: none;
  color: #f5f5f5;
  font-size: 18px;
  
  &:hover {
    background: green;
    cursor: pointer;
  }
`;
  
const SubMenu = ({ item }) => {
  const [subnav, setSubnav] = useState(false);
  
  const showSubnav = () => setSubnav(!subnav);
  
  return (
    <>
      <SidebarLink to={item.path} 
      onClick={item.subNav && showSubnav}>
        <div>
          {item.icon}
          <SidebarLabel>{item.title}</SidebarLabel>
        </div>
        <div>
          {item.subNav && subnav
            ? item.iconOpened
            : item.subNav
            ? item.iconClosed
            : null}
        </div>
      </SidebarLink>
      {subnav &&
        item.subNav.map((item, index) => {
          return (
            <DropdownLink to={item.path} key={index}>
              {item.icon}
              <SidebarLabel>{item.title}</SidebarLabel>
            </DropdownLink>
          );
        })}
    </>
  );
};
  
export default SubMenu;

Ahora que hemos terminado con la carpeta de componentes, ahora manipulamos las páginas. Edite varias páginas para la barra lateral en el proyecto en src/pages:

Nombre de archivo- AboutUs.js:

Javascript

import React from "react";
  
export const AboutUs = () => {
  return (
    <div className="home">
      <h1>GeeksforGeeks About us</h1>
    </div>
  );
};
  
export const OurAim = () => {
  return (
    <div className="home">
      <h1>GeeksforGeeks Aim</h1>
    </div>
  );
};
  
export const OurVision = () => {
  return (
    <div className="home">
      <h1>GeeksforGeeks Vision</h1>
    </div>
  );
};

Nombre de archivo- ContactUs.js:

Javascript

import React from "react";
  
const Contact = () => {
  return (
    <div className="contact">
      <h1>GeeksforGeeks Contact us</h1>
    </div>
  );
};
  
export default Contact;

Nombre de archivo- Events.js:

Javascript

import React from "react";
  
export const Events = () => {
  return (
    <div className="events">
      <h1>GeeksForGeeks Events</h1>
    </div>
  );
};
  
export const EventsOne = () => {
  return (
    <div className="events">
      <h1>GeeksforGeeks Event1</h1>
    </div>
  );
};
  
export const EventsTwo = () => {
  return (
    <div className="events">
      <h1>GeeksforGeeks Event2</h1>
    </div>
  );
};

Nombre de archivo- Services.js:

Javascript

import React from "react";
  
export const Services = () => {
  return (
    <div className="services">
      <h1>GeeksforGeeks Services</h1>
    </div>
  );
};
  
export const ServicesOne = () => {
  return (
    <div className="services">
      <h1>GeeksforGeeks Service1</h1>
    </div>
  );
};
  
export const ServicesTwo = () => {
  return (
    <div className="services">
      <h1>GeeksforGeeks Service2</h1>
    </div>
  );
};
  
export const ServicesThree = () => {
  return (
    <div className="services">
      <h1>GeeksforGeeks Service3</h1>
    </div>
  );
};

Nombre de archivo: Support.js:

Javascript

import React from "react";
  
const Support = () => {
  return (
    <div className="support">
      <h1>GeeksforGeeks Support us</h1>
    </div>
  );
};
  
export default Support;

Todas las páginas y componentes están listos, ahora tenemos que llamarlos uno por uno en nuestro archivo App.js.

Nombre de archivo- App.js:

Javascript

import "./App.css";
import Sidebar from "./components/Sidebar";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { AboutUs, OurAim, OurVision } from "./pages/AboutUs";
import {
  Services,
  ServicesOne,
  ServicesTwo,
  ServicesThree,
} from "./pages/Services";
import { Events, EventsOne, EventsTwo } from "./pages/Events";
import Contact from "./pages/ContactUs";
import Support from "./pages/Support";
function App() {
  return (
    <Router>
      <Sidebar />
      <Switch>
        <Route path="/about-us" exact component={AboutUs} />
        <Route path="/about-us/aim" exact component={OurAim} />
        <Route path="/about-us/vision" exact component={OurVision} />
        <Route path="/services" exact component={Services} />
        <Route path="/services/services1" exact component={ServicesOne} />
        <Route path="/services/services2" exact component={ServicesTwo} />
        <Route path="/services/services3" exact component={ServicesThree} />
        <Route path="/contact" exact component={Contact} />
        <Route path="/events" exact component={Events} />
        <Route path="/events/events1" exact component={EventsOne} />
        <Route path="/events/events2" exact component={EventsTwo} />
        <Route path="/support" exact component={Support} />
      </Switch>
    </Router>
  );
}
  
export default App;

Nombre de archivo- App.css: modifique el CSS de acuerdo con usted.

HTML

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.home,
.services,
.reports,
.contact,
.events,
.support {
  display: flex;
  margin-left: 260px;
  font-size: 2rem;
}

Ejecute el proyecto: guarde todos los archivos e inicie el servidor utilizando el siguiente comando.

npm start

Producción:

Publicación traducida automáticamente

Artículo escrito por gurjotloveparmar y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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