Cómo crear un componente de acordeón con React

Introducción

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: Configuración del proyecto
  • Paso 2: Construcción de los componentes
  • Paso 3: Compatibilidad con múltiples acordeones abiertos
  • Conclusión
  • El instrumento musical acordeón se comprime y se expande. El elemento de control gráfico acordeón se contrae y se expande de manera similar. Esta puede ser una solución para dividir contenido extenso y permitir que los usuarios se concentren en las secciones que son relevantes para ellos.

    De manera similar a un componente de pestañas , un componente de acordeón se compone de diferentes secciones que se pueden abrir y cerrar. A diferencia de un componente de pestañas, los acordeones pueden mostrar varias secciones de contenido al mismo tiempo.

    En este artículo, creará un componente de acordeón simple y reutilizable con secciones que se pueden abrir y cerrar. Luego, modificaremos el componente para que admita tener varias secciones abiertas a la vez y especificaremos qué secciones deben estar abiertas de forma predeterminada.

    Prerrequisitos

    Para completar este tutorial, necesitarás:

    • Node.js instalado localmente, lo cual puedes hacer siguiendo Cómo instalar Node.js y crear un entorno de desarrollo local .
    • Si tienes alguna familiaridad con React, puedes echar un vistazo a nuestra serie Cómo programar en React.js .

    Este tutorial fue verificado con Node v16.6.2, npmv7.21.0 y reactv17.0.2.

    Paso 1: Configuración del proyecto

    En este paso, crearás un nuevo proyecto con Create React App . Luego, eliminarás el proyecto de muestra y los archivos relacionados que se instalan cuando inicias el proyecto.

    Para comenzar, crea un nuevo proyecto. En tu terminal, ejecuta el siguiente script para instalar un nuevo proyecto usando create-react-app:

    1. npx create-react-app react-accordion-component

    Una vez finalizado el proyecto, cambie al directorio:

    1. cd react-accordion-component

    En una nueva pestaña o ventana de la terminal, inicia el proyecto con el script de inicio Create React App . El navegador se actualizará automáticamente cuando se produzcan cambios, así que deja este script ejecutándose mientras trabajas:

    1. npm start

    Esto iniciará un servidor que se ejecuta localmente. Si el proyecto no se abrió en una ventana del navegador, puede abrirlo visitando http://localhost:3000/. Si está ejecutando esto desde un servidor remoto, la dirección será .http://your_domain:3000

    Su navegador se cargará con una plantilla de aplicación React incluida como parte de Create React App:

    Construirás un conjunto completamente nuevo de componentes personalizados, por lo que tendrás que comenzar borrando parte del código repetitivo para poder tener un proyecto vacío.

    Para comenzar, abre src/App.jsun editor de texto. Este es el componente raíz que se inyecta en la página. Todos los componentes comenzarán desde aquí. Puedes encontrar más información sobre App.jsCómo configurar un proyecto de React con Create React App .

    Verás un archivo como este:

    fuente/App.js

    import logo from './logo.svg';import './App.css';function App() {  return (    div className="App"      header className="App-header"        img src={logo} className="App-logo" alt="logo" /        p          Edit codesrc/App.js/code and save to reload.        /p        a          className="App-link"          href="https://reactjs.org"          target="_blank"          rel="noopener noreferrer"                  Learn React        /a      /header    /div  );}export default App;

    Elimine la línea import logo from './logo.svg';. Luego reemplace todo en la returndeclaración para devolver un conjunto de divetiquetas y un h1. Esto le dará una página válida que devuelve un h1que muestra Accordion Demo . El código final se verá así:

    fuente/App.js

    import './App.css';function App() {  return (    div      h1Accordion Demo/h1    /div  );}export default App;

    Guardar y salir del editor de texto.

    Por último, elimine el logotipo. No lo utilizará en su aplicación y deberá eliminar los archivos que no utilice a medida que trabaja. Esto le evitará confusiones a largo plazo.

    En la ventana de terminal escriba el siguiente comando para eliminar el logotipo:

    1. rm src/logo.svg

    Ahora que el proyecto está configurado, puedes crear tu primer componente.

    Paso 2: Construcción de los componentes

    Crearemos tres componentes:

    • Accordion:que contendrá los componentes de nuestra sección y administrará qué secciones están abiertas y cerradas.
    • AccordionSection:que mostrará el título de la sección en la que se puede hacer clic, el contenido de la sección cuando la sección esté abierta e informará acerca de los Accordioneventos de clic.
    • App:¡componente para unir todo en un ejemplo funcional!

    Las secciones dentro del Accordioncomponente serán simplemente divetiquetas que recibirán un labelatributo que se utilizará para la región en la que se puede hacer clic dentro del AccordionSectioncomponente.

    Comencemos creando nuestro componente más interno AccordionSection:

    src/AccordionSection.js

    import React from 'react';import PropTypes from 'prop-types';class AccordionSection extends React.Component {  static propTypes = {    children: PropTypes.instanceOf(Object).isRequired,    isOpen: PropTypes.bool.isRequired,    label: PropTypes.string.isRequired,    onClick: PropTypes.func.isRequired,  };  onClick = () = {    this.props.onClick(this.props.label);  };  render() {    const {      onClick,      props: { isOpen, label },    } = this;    return (      div        style={{          background: isOpen ? '#fae042' : '#6db65b',          border: '1px solid #008f68',          padding: '5px 10px',        }}              div onClick={onClick} style={{ cursor: 'pointer' }}          {label}          div style={{ float: 'right' }}            {!isOpen  span#9650;/span}            {isOpen  span#9660;/span}          /div        /div        {isOpen  (          div            style={{              background: '#6db65b',              border: '2px solid #008f68',              marginTop: 10,              padding: '10px 20px',            }}                      {this.props.children}          /div        )}      /div    );  }}export default AccordionSection;

    Este componente recibirá una labelpropiedad que creará el título en el que se puede hacer clic de la sección. La onClickpropiedad del controlador de eventos se utiliza para informar al componente principal si se ha hecho clic en la etiqueta.

    El componente principal se encargará de realizar el seguimiento de qué secciones están abiertas o cerradas y enviará el estado AccordionSectioncomo una propiedad booleana isOpen.

    Cualquier componente secundario AccordionSectionse mostrará solo si la sección se ha activado para abrir y la propiedad isOpenes verdadera.

    Ahora que tenemos un componente para nuestras secciones, necesitamos un componente que albergue estas secciones y administre el estado de qué secciones se han abierto o cerrado:

    fuente/Accordion.js

    import React from 'react';import PropTypes from 'prop-types';import AccordionSection from './AccordionSection';class Accordion extends React.Component {  static propTypes = {    children: PropTypes.instanceOf(Object).isRequired,  };  constructor(props) {    super(props);    const openSections = {};    this.state = { openSections };  }  onClick = label = {    const {      state: { openSections },    } = this;    const isOpen = !!openSections[label];    this.setState({      openSections: {        [label]: !isOpen      }    });  };  render() {    const {      onClick,      props: { children },      state: { openSections },    } = this;    return (      div style={{ border: '2px solid #008f68' }}        {children.map(child = (          AccordionSection            isOpen={!!openSections[child.props.label]}            label={child.props.label}            onClick={onClick}                      {child.props.children}          /AccordionSection        ))}      /div    );  }}export default Accordion;

    ¡Genial! Nuestro Accordioncomponente recibirá nodos secundarios que se utilizarán para crear nuestros AccordionSectioncomponentes interactivos.

    Este componente rastrea qué sección se ha abierto, pero solo mantiene un registro de una sola sección abierta a la vez (por ahora).

    ¡Una vez creados nuestros componentes Accordiony AccordionSection, ahora podemos crear nuestro Appcomponente y ver las cosas en acción!

    Para nuestra demostración de acordeón, crearemos un acordeón Accordioncon dos componentes secundarios que contienen algunos datos sobre los caimanes:

    fuente/App.js

    import Accordion from './Accordion';function App() {  return (    div      h1Accordion Demo/h1      Accordion        div label='Alligator Mississippiensis'          p            strongCommon Name:/strong American Alligator          /p          p            strongDistribution:/strong Texas to North Carolina, US          /p          p            strongEndangered Status:/strong Currently Not Endangered          /p        /div        div label='Alligator Sinensis'          p            strongCommon Name:/strong Chinese Alligator          /p          p            strongDistribution:/strong Eastern China          /p          p            strongEndangered Status:/strong Critically Endangered          /p        /div      /Accordion    /div  );}export default App;

    Contiene Accordiondos secciones que, al hacer clic para abrirlas, mostrarán algunos datos sobre diferentes especies de caimanes.

    Paso 3: Compatibilidad con múltiples acordeones abiertos

    Todo lo que hemos creado hasta ahora es utilizable, pero algo limitado, ya que solo se puede abrir una sección a la vez y todas las secciones están contraídas de forma predeterminada.

    Para agregar soporte para que múltiples secciones estén abiertas al mismo tiempo, vamos a agregar una propiedad llamada allowMultipleOpenal Accordioncomponente que se usará para indicarle al acordeón si debe permitir que múltiples secciones estén abiertas.

    Cuando está habilitado, el estado alternará las claves individuales entre verdadero y falso en lugar de sobrescribir completamente el estado con la sección con la que se interactuó.

    Mientras estamos allí, podemos agregar algo de lógica adicional para verificar los nodos secundarios en busca de una isOpenpropiedad. Cuando esté presente, el estado abierto se inicializará y la sección ya estará marcada como abierta:

    fuente/Accordion.js

    import React from 'react';import PropTypes from 'prop-types';import AccordionSection from './AccordionSection';class Accordion extends React.Component {  static propTypes = {    allowMultipleOpen: PropTypes.bool,    children: PropTypes.instanceOf(Object).isRequired,  };  constructor(props) {    super(props);    const openSections = {};    this.props.children.forEach(child = {      if (child.props.isOpen) {        openSections[child.props.label] = true;      }    });    this.state = { openSections };  }  onClick = label = {    const {      props: { allowMultipleOpen },      state: { openSections },    } = this;    const isOpen = !!openSections[label];    if (allowMultipleOpen) {      this.setState({        openSections: {          ...openSections,          [label]: !isOpen        }      });    } else {      this.setState({        openSections: {          [label]: !isOpen        }      });    }  };  render() {    const {      onClick,      props: { children },      state: { openSections },    } = this;    return (      div style={{ border: '2px solid #008f68' }}        {children.map(child = (          AccordionSection            isOpen={!!openSections[child.props.label]}            label={child.props.label}            onClick={onClick}                      {child.props.children}          /AccordionSection        ))}      /div    );  }}export default Accordion;

    Una vez que estamos Accordionlistos para aceptar nuevos parámetros, podemos actualizar nuestro Appcomponente para pasar la propiedad y permitir que se abran varias secciones, así como marcar la primera sección para que se abra de manera predeterminada:

    fuente/App.js

    import Accordion from './Accordion';function App() {  return (    div      h1Accordion Demo/h1      Accordion allowMultipleOpen        div label='Alligator Mississippiensis' isOpen          p            strongCommon Name:/strong American Alligator          /p          p            strongDistribution:/strong Texas to North Carolina, US          /p          p            strongEndangered Status:/strong Currently Not Endangered          /p        /div        div label='Alligator Sinensis'          p            strongCommon Name:/strong Chinese Alligator          /p          p            strongDistribution:/strong Eastern China          /p          p            strongEndangered Status:/strong Critically Endangered          /p        /div      /Accordion    /div  );}export default App;

    Ahí lo tienes, un componente de acordeón reutilizable que te ayudará a controlar el contenido rebelde.

    Conclusión

    En este artículo, creó un componente de acordeón simple y reutilizable con secciones que se pueden abrir y cerrar.

    Continúa tu aprendizaje anidando estos acordeones para satisfacer incluso los escenarios más complejos.

    Puede encontrar una demostración funcional y el código de este artículo en CodeSandbox .

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

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

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion