Как реализовать табы в Реакте, не используя хуки
Создал табы на чистом CSS: https://codepen.io/syberian/pen/RwBBqGq - и эти табы отлично работают в песочнице.
HTML
<div class='match-outcome'>
<ul class='tabs'>
<li class='tab'>
<input class='switcher' type="radio" id="tab-1" name="tabs" checked />
<label for="tab-1">Победы</label>
<div class="tab-content">
<p>ПОБЕДЫ.</p>
</div>
</li>
<li class='tab'>
<input class='switcher' type="radio" id="tab-2" name="tabs" />
<label for="tab-2">Поражения</label>
<div class="tab-content">
<p>ПОРАЖЕНИЯ.</p>
</div>
</li>
<li class=tab>
<input class='switcher' type="radio" id="tab-3" name="tabs" />
<label for="tab-3">Ничьи</label>
<div class="tab-content">
<p>НИЧЬИ.</p>
</div>
</li>
</ul>
</div>
СSS
.match-outcome {
max-width: 684px;
margin: 0 auto;
padding: 6rem 0 2.5rem;
}
.tabs {
position: relative;
min-height: 315px;
display: flex;
margin: 0;
padding: 0;
list-style: none;
overflow: hidden;
}
.tab {
flex: 1;
}
.tab label {
display: block;
box-sizing: border-box;
height: 32px;
font-family: 'Montserrat', sans-serif;
font-size: 1.5rem;
font-weight: 600;
line-height: 2rem;
letter-spacing: 0em;
text-align: center;
cursor: pointer;
transition: background 0.6s ease;
}
.tab label:hover {
color: lightblue;
}
.tab-content {
position: absolute;
left: 0;
bottom: 0;
right: 0;
top: 32px;
padding-top: 1rem;
background: #cfc0e3;
transition: opacity 0.6s ease, transform 0.6s ease;
opacity: 0;
transform: scaleX(0);
transform-origin: top center;
}
.tab [type=radio] {
display: none;
}
.switcher:checked ~ label {
color: blue;
}
.switcher:checked ~ .tab-content {
opacity: 1;
transform: scaleX(1);
}
Но эти табы не работают в Реакте. Проблема заключается в том что одному из табов в разметке установлен атрибут checked (убрать его я не могу, он задаёт начальный контент, при загрузке странице). Из-за этого при ререндере компонента, checked всегда стоит на первом табе и вкладки переключаются не корректно. При нажатии на любую вкладку, кроме первой, переключение почему-то происходит только со ВТОРОГО раза. А при первом нажатии всегда перебрасывает на первую вкладку.
Хуки я не хочу ПОКА использовать, т.к. это реакт-компонент на самом деле будет использоваться в NextJS. И мне почему-то сказали чтобы я пока не использовал хуки, а просто верстал компоненты, без сложной логики.
Есть ли какой-то простой способ решить эту проблему? Можно ли без хуков, написать код на TS который реализует нужный мне функционал табов?
Я пока пытаюсь сообразить, как с помощью TS переключать на каждом табе checked={true}
и checked={false}
.
UPD. По просьбам из комментариев, публикую JSX с по сути такой же разметкой как и выше, если не учитывать особенности синтаксиса в реакте. СSS не выкладываю, т.к. он уже выше был скопирован как раз из рабочего проекта.
import styles from './Styles.module.css'
<div className={styles['match-outcome']}>
<ul className={styles.tabs}>
<li className={styles.tab}>
<input className={styles.switcher} type="radio" id="tab-1" name="tabs" checked={true} />
<label htmlFor="tab-1">Победы</label>
<div className={styles["tab-content"]}>
<p>ПОБЕДЫ.</p>
</div>
</li>
<li className={styles.tab}>
<input className={styles.switcher} type="radio" id="tab-2" name="tabs" />
<label htmlFor="tab-2">Поражения</label>
<div className={styles["tab-content"]}>
<p>ПОРАЖЕНИЯ.</p>
</div>
</li>
<li className={styles.tab}>
<input className={styles.switcher} type="radio" id="tab-3" name="tabs" />
<label htmlFor="tab-3">Ничьи</label>
<div className={styles["tab-content"]}>
<p>НИЧЬИ.</p>
</div>
</li>
</ul>
</div>