Для визуального офомрления компонентов сейчас используем css-классы а так же бэм-модификаторы, которые строим в рантайме на каждый рендер компонента:
const cnButton = cn('Button')
const Button = ({ size, view, children }) => {
return (
<button
className={cnButton({ size, view })}
>
{children}
</button>
)
}
.Button_size_m {
height: 36px;
font-size: 15px;
}
.Button_view_default {
border: 0;
border-radius: 4px;
background-color: bisque;
}
- Удобно работать с dev-tools (можно тоглить классы)
- Дополнительный размер бандла (пускай и не значительный)
- Рантайм вычисления, каждый ре-рендер приводит к повторному построению класса (требуется мемоизация)
- Для обеспечения доступности, например когда элемент не доступен, приходится писать дублирующую информацию:
<button className={cnButton({ disabled })} aria-disabled={disabled} />
.Button_disabled { cursor: default; }
const Button = ({ size, view, children }) => {
return (
<button
className="Button"
data-size={size}
data-view={view}
>
{children}
</button>
)
}
.Button[data-size="m"] {
height: 36px;
font-size: 15px;
}
.Button[data-view="default"] {
border: 0;
border-radius: 4px;
background-color: bisque;
}
- Нету никакого дополнительного кода в бандле
- Нет рантайм вычислений
- Для доступности используем все те же атрибуты (не перемешиваем несколько подходов):
<button className="Button" aria-disabled={disabled} />
.Button[aria-disabled="true"] { cursor: default; }
- При необходимости можно легко достать нужное значение, т.к.
dataset
является объектом, не нужно парсить строку с классом
- Нет возможности так же удобно работать в dev-tools как с классами
Можно поймать сайд-эффект при композиции двух компонентов: