🟨 React
Легкая
🕐 1 story point

React: Чекбоксы с ограничением выбора

Сделай контролируемые чекбоксы и запрети выбирать больше двух. При попытке выбрать третий — выбор должен игнорироваться, а пользователь увидит аккуратное предупреждение.

Александр, тимлид React-стажировки

Бизнес-кейс. Клиент собирает MVP-пакет: можно включить лишь две функции, чтобы сфокусироваться на ценности.

Что нужно сделать

  • Создай состояние для выбранных опций (массив или множество).
  • Сделай чекбоксы контролируемыми: checked берётся из состояния, обновляется по onChange.
  • Ограничь выбор максимум двумя. Третья попытка — блокируется, покажи предупреждение.

Финальный вид

Карточка с тремя чекбоксами, счётчиком вида N/2 выбрано и мягким предупреждением при превышении лимита. Финальный результат можно представить так: Пример карточки

💡 Подсказка
  • Храни выбранные названия в состоянии: const [selected, setSelected] = useState([]).
  • В обработчике проверяй лимит: если уже выбрано 2 и пользователь пытается добавить третью — не обновляй состояние, покажи сообщение.
  • Для UX используй короткое предупреждение в role="alert" и aria-live (по желанию).
  • Документация React:
👀 Решение
import React, { useState } from 'react';
import './styles.css';
 
export function FeatureSelector({ options = ['Аналитика', 'Уведомления', 'Приоритетная поддержка'] }) {
  const [selected, setSelected] = useState([]);
  const [warning, setWarning] = useState('');
 
  function handleToggle(name) {
    const isChecked = selected.includes(name);
 
    if (isChecked) {
      setSelected(selected.filter((n) => n !== name));
      setWarning('');
      return;
    }
 
    if (selected.length >= 2) {
      setWarning('Лимит достигнут: можно выбрать не более двух.');
      return;
    }
 
    setSelected([...selected, name]);
    setWarning('');
  }
 
  const count = selected.length;
 
  return (
    <article className="card" data-testid="feature-card">
      <header>
        <h2 className="title">Выбери функции для MVP</h2>
        <p className="subtitle">Можно выбрать не более двух</p>
      </header>
 
      <div className="options">
        {options.map((name) => (
          <label key={name} className="option">
            <input
              className="checkbox"
              type="checkbox"
              checked={selected.includes(name)}
              onChange={() => handleToggle(name)}
            />
            <span>{name}</span>
          </label>
        ))}
      </div>
 
      <div className="counter-row">
        <p className="counter" aria-label="counter">{count}/2 выбрано</p>
        {warning && <p role="alert" className="warning">{warning}</p>}
      </div>
    </article>
  );
}
 
export default function App() {
  const features = ['Аналитика', 'Уведомления', 'Приоритетная поддержка'];
  return (
    <main className="challenge-container">
      <section>
        <FeatureSelector options={features} />
      </section>
    </main>
  );
}

🧑‍💻 Это не баг! Это фича!

Редактор кода намеренно скрыт на мобильном.

Поверь, так лучше: я оберегаю тебя от искушения писать код в неидеальных условиях. Маленький экран и виртуальная клавиатура — не лучшие помощники для программиста.

📖 Сейчас: Изучи задачу, продумай решение. Действуй как стратег.

💻 Потом: Сядь за компьютер, открой сайт и реализуй все идеи с комфортом. Действуй как код-джедай!