Crear un menú acordeón en React sin plugin

El «menú acordeón» o también llamado en inglés accordion / collapse menu, es una de las opciones que tenemos para maquetar mucha información en un espacios pequeños y que se fácil para el usuario de visualizar y/o ocultar el contenido. Crear uno de menú acordeón en React js, es bastante sencillo si usamos frameworks como Bootstrap, Material UI o similares. Pero se nos «complica» para los que usamos Bulma CSS y no tiene dicha opción.

En este tutorial «rapido» y sin vueltas, describiré cómo crear un menú acordeón en React que puede ser usado en secciones como preguntas frecuentes (FAQ’s) por dar un ejemplo.

El menú acordeón incorpora la divulgación de la información progresiva, proporciona una interfaz de usuario limpia y minimiza el desplazamiento, especialmente en pantallas pequeñas, lo que es beneficioso para los dispositivos móviles.

acordeón en React

Y si creamos un menú acordeón en React?

Como siempre, me salto toda la parte de instalación de React, ya sea con create-react-app o vite

Primero vamos a crear un nuevo componente al que llamaremos Accordion.js (en inglés por si tenemos un equipo.) y para nuestro ejemplo vamos a crear un variable con unos objetos que simularán ser la misión, visión y valores de una empresa.

const aboutUs = [
  {
    title: "Mision",
    content: "Nuestros valores",
  },
  {
    title: "Vision",
    content: "Nuestra vision",
  },
  {
    title: "Valores",
    content: "Nuestros valores",
  }
]

*Recordar que esta constante puede ser un state con datos que consumidos desde una API.

Importamos React y también importamos un componente llamado que crearemos después llamado Collapse.js y mapearemos nuestra variable/state y se lo enviamos a nuestro componente de la siguiente manera.

export const Accordion = () => {
  return (
    <div className="column">
      {aboutUs.map((item, index) => {
        return (
          <Collapse key={index} title={item.title} collapsed>
            <p>{item.content}</p>
          </Collapse>
        )
      })}
    </div>
  )
}

Al nuevo componente Collapse le estará llegando por props:

  • title: Vendría ser el header visible del menú acordeón.
  • collapse: esta opción nos mostrará el contenido visible o oculto del menú. Por defecto, todos estarán ocultos.
  • children: Todo que haya dentro del componente, en este caso «<p>{item.content}</p>«

Pasamos a crear el siguiente componente y más importante: Collapse.js

import React, { useState } from 'react'

export const Collapse = ({ title, collapsed, children }) => {
  const [isCollapsed, setIsCollapsed] = useState(collapsed)

  return (
    <div className="mb-2">
      <header
        className={`collapse__header is-flex is-align-items-center is-justify-content-space-between`}
        onClick={() => setIsCollapsed(!isCollapsed)}
      >
        <h3 className="collapse__title is-size-6 has-text-weight-bold">
          {title}
        </h3>
        {isCollapsed ? "+" : "-"}
      </header>
      <div
        className={`collapse__content notification ${
          isCollapsed ? "collapsed" : "expanded"
        }`}
        aria-expanded={isCollapsed}
      >
        {children}
      </div>
    </div>
  )
}
  1. Hacemos uso de useState para guardar es estado del acordeón, si está abierto o cerrado. [isCollapsed, setIsCollapsed] = useState(collapsed)
  2. En el header del menú el estado del estado cambiará, si está oculto o visible el collll?ntenido onClick={() => setIsCollapsed(!isCollapsed)}
  3. En un <h3> imprimimos el título que enviamos por props.
  4. Lo siguiente y último es preguntar si está visible u oculto el contenido que enviamos por {children}

El en punto 4, el bloque de código tiene unas clases de css que vamos a necesitar, pero ademas de eso, yo ademas le agregue algunos estilos con Bulma CSS.

.collapse__content.collapsed {
    display: none;
}  
.collapsed__content.expanded {
    display: block;
}

*Se podría hacer solo con bulma, pero para el ejemplo lo tengo que agregar.

Existen distintas librerías para crear un acordeón en react y podría hacerse de manera mucho más rápida o con frameworks de CSS que ya tienen declaradas las clases para crear un menú collapse.