От автора: как вы, возможно, знаете, есть много приложений, использующих контейнер accordions, таких как отображение списка часто задаваемых вопросов, различных меню и подменю, для отображения различных местоположений конкретной компании и так далее. Итак, в этой статье мы рассмотрим, как построить accordion в React полностью с нуля, шаг за шагом, без использования какой-либо внешней библиотеки.
Мы будем использовать синтаксис React Hooks для создания приложения в React. Вы можете увидеть демонстрацию приложения здесь. Итак, приступим.
Начальная настройка проекта
Создайте новый проект, используя create-react-app:
1 |
npx create-react-app react-accordion-demo |
После того, как проект будет создан, удалите все файлы из папки src и создайте файлы index.js, App.js и styles.css внутри src. Также, внутри папки src, создайте новую папку с именем utils. Откройте файл styles.css и добавьте в него содержимое отсюда.
Как создать начальные страницы
Откройте файл src/App.js и добавьте в него следующий контент:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import React from 'react'; const App = () => { const accordionData = { title: 'Section 1', content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis sapiente laborum cupiditate possimus labore, hic temporibus velit dicta earum suscipit commodi eum enim atque at? Et perspiciatis dolore iure voluptatem.` }; const { title, content } = accordionData; return ( <React.Fragment> <h1>React Accordion Demo</h1> <div className="accordion"> <div className="accordion-item"> <div className="accordion-title"> <div>{title}</div> <div>+</div> </div> <div className="accordion-content">{content}</div> </div> </div> </React.Fragment> ); }; export default App; |
Здесь мы используем свойства объекта accordionData для отображения содержимого контейнера accordion. Для свойства content мы используем синтаксис литерала шаблона ES6 (), чтобы мы могли распределить контент по нескольким строкам, и мы использовали фиктивный текст lorem ipsum.
Теперь откройте файл src/index.js и добавьте в него следующее содержимое:
1 2 3 4 5 6 |
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import './styles.css'; ReactDOM.render(<App />, document.getElementById('root')); |
Теперь, если вы запустите приложение с помощью команды yarn start из терминала, вы увидите следующий экран:
Как открывать и закрывать контейнер accordion
Как вы можете видеть выше, мы отображаем один раздел как часть accordion, но по умолчанию мы не можем закрыть accordion. Итак, давайте добавим функционал для открытия и закрытия accordion. Добавьте новое состояние внутри компонента, как показано ниже:
1 |
const [isActive, setIsActive] = useState(false); |
Здесь мы определили состояние isActive и на его основе скроем или покажем содержимое контейнера. Также импортируйте хук useState в верхней части файла:
1 |
import React, { useState } from 'react'; |
Теперь для div с классом accordion-title добавьте обработчик onClick следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 |
<div className="accordion"> <div className="accordion-item"> <div className="accordion-title" onClick={() => setIsActive(!isActive)} > <div>{title}</div> <div>{isActive ? '-' : '+'}</div> </div> {isActive && <div className="accordion-content">{content}</div>} </div> </div> |
Здесь мы инвертируем значение состояния isActive, когда нажимаем на div accordion-title. Если значение isActive равно false, мы устанавливаем его на true и наоборот.
Мы также устанавливаем знак + или — в зависимости от значения isActive используя тернарный оператор. И если значение состояния isActive равно true то мы показываем содержимое контейнера, как показано ниже:
1 |
{isActive && <div className="accordion-content">{content}</div>} |
Теперь, если вы проверите приложение, вы увидите следующий экран:
Как видите, изначально контейнер закрыт, и при нажатии на заголовок открывается accordion, и мы можем кликнуть по нему еще раз, чтобы закрыть.
Как добавить несколько разделов в контейнер accordion
Это хорошо работает для одного раздела accordion, но если у нас есть несколько разделов, копировать и вставлять один и тот же код JSX снова и снова с разным содержимым – плохое решение.
Давайте создадим отдельный компонент, чтобы просто отображать accordion, и в зависимости от количества разделов мы перейдем к компоненту, чтобы отобразить несколько разделов. Создайте новый файл Accordion.js внутри папки src и добавьте в него следующее содержимое:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import React, { useState } from 'react'; const Accordion = ({ title, content }) => { const [isActive, setIsActive] = useState(false); return ( <div className="accordion-item"> <div className="accordion-title" onClick={() => setIsActive(!isActive)}> <div>{title}</div> <div>{isActive ? '-' : '+'}</div> </div> {isActive && <div className="accordion-content">{content}</div>} </div> ); }; export default Accordion; |
Здесь мы перемещаем состояние div accordion-item из файла App.js в файл Accordion.js и передаем title и content props, используя синтаксис деструктуризации ES6, например:
1 |
const Accordion = ({ title, content }) => { |
Теперь откройте App.js файл и замените его следующим содержимым:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import React from 'react'; import Accordion from './Accordion'; const App = () => { const accordionData = [ { title: 'Section 1', content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis sapiente laborum cupiditate possimus labore, hic temporibus velit dicta earum suscipit commodi eum enim atque at? Et perspiciatis dolore iure voluptatem.` }, { title: 'Section 2', content: `Lorem ipsum, dolor sit amet consectetur adipisicing elit. Mollitia veniam reprehenderit nam assumenda voluptatem ut. Ipsum eius dicta, officiis quaerat iure quos dolorum accusantium ducimus in illum vero commodi pariatur? Impedit autem esse nostrum quasi, fugiat a aut error cumque quidem maiores doloremque est numquam praesentium eos voluptatem amet! Repudiandae, mollitia id reprehenderit a ab odit!` }, { title: 'Section 3', content: `Sapiente expedita hic obcaecati, laboriosam similique omnis architecto ducimus magnam accusantium corrupti quam sint dolore pariatur perspiciatis, necessitatibus rem vel dignissimos dolor ut sequi minus iste? Quas?` } ]; return ( <div> <h1>React Accordion Demo</h1> <div className="accordion"> {accordionData.map(({ title, content }) => ( <Accordion title={title} content={content} /> ))} </div> </div> ); }; export default App; |
Здесь мы преобразовали accordionData из объекта в массив объектов и мы проходим его, передавая соответствующие title и content компоненту Accordion.
Теперь, если вы запустите приложение, вы увидите, что отображаются три раздела, и мы можем открывать и закрывать каждый раздел, как показано ниже:
Рефакторинг кода
Как вы можете видеть, просто переместив секцию accordion в отдельный компонент и передав динамический контент в качестве реквизита, мы успешно можем создать рабочую версию accordion с нуля.
Лучше хранить статические данные в отдельном файле. Давайте переместим массив accordionData в другой файл и импортируем его в файл App.js. Создайте новый файл content.js внутри папки utils и добавьте в него следующее содержимое:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
export const accordionData = [ { title: 'Section 1', content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis sapiente laborum cupiditate possimus labore, hic temporibus velit dicta earum suscipit commodi eum enim atque at? Et perspiciatis dolore iure voluptatem.` }, { title: 'Section 2', content: `Lorem ipsum, dolor sit amet consectetur adipisicing elit. Mollitia veniam reprehenderit nam assumenda voluptatem ut. Ipsum eius dicta, officiis quaerat iure quos dolorum accusantium ducimus in illum vero commodi pariatur? Impedit autem esse nostrum quasi, fugiat a aut error cumque quidem maiores doloremque est numquam praesentium eos voluptatem amet! Repudiandae, mollitia id reprehenderit a ab odit!` }, { title: 'Section 3', content: `Sapiente expedita hic obcaecati, laboriosam similique omnis architecto ducimus magnam accusantium corrupti quam sint dolore pariatur perspiciatis, necessitatibus rem vel dignissimos dolor ut sequi minus iste? Quas?` } ]; |
Теперь откройте файл App.js и замените его следующим содержимым:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import React from 'react'; import Accordion from './Accordion'; import { accordionData } from './utils/content'; const App = () => { return ( <div> <h1>React Accordion Demo</h1> <div className="accordion"> {accordionData.map(({ title, content }) => ( <Accordion title={title} content={content} /> ))} </div> </div> ); }; export default App; |
Здесь мы только что импортировали статические данные из внешнего файла и удалили их из App.js. Итак, теперь код выглядит чистым и легким для понимания, а функционал работает, как и раньше.
Мы закончили с функционалом приложения. Вы можете найти полный исходный код GitHub для этого приложения в этом репозитории.
Автор: Yogesh Chavan
Источник: yogeshchavan.hashnode.dev
Редакция: Команда webformyself.
Читайте нас в Telegram, VK, Яндекс.Дзен