Урок 16. Частые ошибки
⚡ Кратко
Ждать от реестра поведения библиотеки, бояться править скопированный код, обновлять компоненты вслепую и терять единообразие в команде.
Ошибка 1. Искать пакет shadcn/ui в зависимостях
Как проявляется: «а какую версию библиотеки мы используем?» — вопрос без ответа, потому что библиотеки нет.
Как правильно: версия у вас одна — та, что в момент копирования попала в файлы. Узнать различия с реестром можно так:
npx shadcn@latest add button --diff
Ошибка 2. Бояться менять скопированный код
Как проявляется: вместо правки компонента разработчик обвешивает его обёртками и переопределениями снаружи — и получает те же проблемы, что и с чужой библиотекой.
Как правильно: это ваш файл. Нужен новый вариант — добавьте
в cva. Не нужен вариант — удалите. Именно ради этого исходник
и копируется в проект.
Ошибка 3. Слепое повторное добавление
Как ломается: команда
add --overwrite затирает ваши правки, и интерфейс возвращается
к состоянию «из коробки».
npx shadcn@latest add button --diff # сначала посмотреть отличия
npx shadcn@latest add button --dry-run # затем — что именно изменится
Как правильно: компоненты живут в git. Перед обновлением — чистое рабочее дерево, после — обычный code review диффа.
Ошибка 4. Пять кнопок в одном проекте
Как проявляется: у каждого разработчика своя версия компонента, потому что «проще скопировать ещё раз».
Как правильно: договориться, что components/ui
— общая зона, изменения в ней проходят ревью. Свобода правки не отменяет
необходимости единого источника правды.
Ошибка 5. Игнорировать примитив
Как ломается: разработчик заменяет
DialogPrimitive.Popup на обычный div, потому что
«так проще», — и теряет фокус-ловушку, Esc и блокировку прокрутки.
Как правильно: менять оформление — да, менять слой поведения — только осознанно. Всё, что примитив делает незаметно, придётся реализовать самому.
Ошибка 6. Копировать код из статей под старую версию
Смешение API Radix и Base UI в одном проекте — источник странных ошибок:
asChild не работает там, где ждут render, а
data-[state=open] не срабатывает там, где примитив ставит
data-open. Ориентируйтесь на исходник в своём проекте —
он всегда актуальнее статьи.