как мне написать логику для такого своего рода аккордеона на react?

Рейтинг: 0Ответов: 2Опубликовано: 01.02.2023


Нужно чтобы при переключении радио-кнопок менялась карточка (second-section__cards-item). Не могу сообразить как это сделать на ReactJS((

.second-section
  color: white
  padding: 100px 0 110px 0
  background: #000
  &__cards
    margin-bottom: 45px
    &-item
      border: solid 2px white
      border-radius: 20px
      display: flex
      justify-content: space-between
      height: 436px

      padding-left: 78px
      overflow: hidden
      &-title
        margin-top: 77px
        font-size: 64px
        font-weight: 700
      &-slider
        margin-top: 80px
        font-size: 24px
        font-weight: 400
        width: 639px
        height: 145px
      &-num
        margin-top: 73px
        font-family: 'Intro'
        font-size: 350px
        line-height: 350px
        transform: translateX(45px)
  &__change-card
    font-size: 32px
    font-weight: 500
    width: 635px
    height: 50px
    display: flex
    align-items: center
    justify-content: space-between

<div className='second-section__cards'>
  <div className='second-section__cards-item'>
    <div className='second-section__cards-item-title'>Дизайн</div>
    <div className='second-section__cards-item-slider'>
      <div className='second-section__cards-item-slider-desc_prev'>
        Создадим продающий, удобный и стильный дизайн, отражающий специфику и индивидуальность вашего бизнеса. Подберём цвета и типографику, сделаем прототип и адаптивный макет для всех популярных устройств.
      </div>
      <div className='second-section__cards-item-slider-next' style={{display: 'none'}}>
        Что входит в разработку дизайна: <br />• Прототип лендинга/многостраничного сайта • Подбор цветов и типографики • Дизайн сайта «от» и «до» • Адаптивный макет
      </div>
    </div>
    <div className='second-section__cards-item-num keyword_green'>1</div>
  </div>
  <div className='second-section__cards-item' style={{display: 'none'}}>
    <div className='second-section__cards-item-title'>Дизайн</div>
    <div className='second-section__cards-item-slider'>
      <div className='second-section__cards-item-slider-desc_prev'>
        Создадим продающий, удобный и стильный дизайн, отражающий специфику и индивидуальность вашего бизнеса. Подберём цвета и типографику, сделаем прототип и адаптивный макет для всех популярных устройств.
      </div>
      <div className='second-section__cards-item-slider-next' style={{display: 'none'}}>
        Что входит в разработку дизайна: <br />• Прототип лендинга/многостраничного сайта • Подбор цветов и типографики • Дизайн сайта «от» и «до» • Адаптивный макет
      </div>
    </div>
    <div className='second-section__cards-item-num keyword_green'>1</div>
  </div>
  <div className='second-section__cards-item' style={{display: 'none'}}>
    <div className='second-section__cards-item-title'>Дизайн</div>
    <div className='second-section__cards-item-slider'>
      <div className='second-section__cards-item-slider-desc_prev'>
        Создадим продающий, удобный и стильный дизайн, отражающий специфику и индивидуальность вашего бизнеса. Подберём цвета и типографику, сделаем прототип и адаптивный макет для всех популярных устройств.
      </div>
      <div className='second-section__cards-item-slider-next' style={{display: 'none'}}>
        Что входит в разработку дизайна: <br />• Прототип лендинга/многостраничного сайта • Подбор цветов и типографики • Дизайн сайта «от» и «до» • Адаптивный макет
      </div>
    </div>
    <div className='second-section__cards-item-num keyword_green'>1</div>
  </div>
</div>
<div className='second-section__change-card'>
  <div className='second-section__change-card_form'>
    <input id='design' type='radio' name='radio' defaultChecked={true} />
    <label htmlFor='design'>Дизайн</label>
  </div>
  <div className='second-section__change-card_form'>
    <input id='frontend' type='radio' name='radio' />
    <label htmlFor='frontend'>Frontend</label>
  </div>
  <div className='second-section__change-card_form'>
    <input id='backend' type='radio' name='radio' />
    <label htmlFor='backend'>Backend</label>
  </div>
</div>

Ответы

▲ 0

Сократим немного входные данные, пусть они выглядят так:

const radioData = [
  { 
    block: <div>Дизайн блок</div>,
    radioText: 'Дизайн',
    radioKey: 'design'
  },
  { 
    block: <div>Фронтенд реализация</div>,
    radioText: 'Фронтенд',
    radioKey: 'frontend'
  },
  { 
    block: <div>Бэкенд контент</div>,
    radioText: 'Бэккнд',
    radioKey: 'backend'
  },
]

Тогда в компоненте создаем 2 состояния:

const [blockRender, setBlockRender] = useState(radioData); // Сами данные
const [selectRadio, setSelectRadio] = useState(0); // Выбранный блок

И в методе render добавляем вывод:

return (
  <div>
    {blockRender.map((item, index) =>
      <div key={item.radioKey}>
        <input
          id={item.radioKey}
          type='radio'
          name='radio'
          onClick={() => setSelectRadio(index)}
        />
        <label htmlFor={item.radioKey}>{item.radioText}</label>
      </div>
    )}
    <br/>
    {blockRender[selectRadio].block}
  </div>
)
▲ 0

Доброго времени суток.

// Для начала необходимо создать массив с элементами.
// Поскольку у нас изменяется только содержание, можно особо не заморачиваться.
// и вынести в массив основные моменты.
// Обязательно оставляем для себя id или любой другой тип, за который 
// потом сможем зацепиться при рендере.

const cards = [{
  id: 0,
  title: 'Дизайн',
  description: 'Описание',
  img: '/src/img.png'
}, {
  id: 1,
  title: 'Frontend',
  description: 'Описание',
  img: '/src/img.png'
}, {
  id: 2,
  title: 'Backend',
  description: 'Описание',
  img: '/src/img.png'
}]

// Затем объявим стейт, где будет храниться текущая карточка.

const [currentCard, setCurrentCard] = useState(0) // По-умолчанию покажем первую карточку.

// Затем необходимо отрендерить выбранную карточку, а также кнопки
return (
<>
  {cards.map((card, i) => (
    <button key={`buttonCard-${i}`} onClick={() => setCurrentCard(card.id)}>
      {card.title}
    </button>
  ))}

  {cards.map((card, i) => {
    return card.id === currentCard ? (
      <div key={`card-${i}`} className='card'>
        <div className='title'> {card.title} </div>
        <div className='title'> {card.description} </div>
        <img src={card.img} />
      </div>
    ) : undefined
  })}
</>
  )

Также для плавности смены карточек можно использовать CSSTransition