jb

Функция для classnames

При работе с условными CSS классами разработчики часто формируют className вручную, что делает код трудночитаемым и подверженным ошибкам.

import type { ComponentProps, ReactNode } from "react";

import styles from './Button.module.css'

interface ButtonProps extends ComponentProps<"button"> {
  children: ReactNode;
  selected?: boolean;
  variant?: "primary" | "secondary";
  ...
}

const Button = ({ variant = "primary", selected = false, children, ...props }: ButtonProps) => (
  <button className={`${styles.button} ${styles[variant]} ${selected ? styles.selected : ''}`} {...props}>
    {children}
  </button>
);

Такой код сложно читать и легко сломать пробелами. clsx делает то же самое короче и понятнее:

import type { ComponentProps, ReactNode } from "react";
import clsx from "clsx";

import styles from './Button.module.css'

interface ButtonProps extends ComponentProps<"button"> {
  children: ReactNode;
  selected?: boolean;
  variant?: "primary" | "secondary";
  ...
}

const Button = ({ variant = "primary", selected = false, children, ...props }: ButtonProps) => (
  <button className={clsx(styles.button, styles[variant], selected && styles.selected)} {...props}>
    {children}
  </button>
);

clsx игнорирует falsy-значения и правильно склеивает классы. В итоге условная стилизация читается быстрее и проще поддерживается. Особенно заметна польза в компонентах с несколькими состояниями (variant, size, disabled, selected), где ручные шаблонные строки быстро становятся хрупкими.

Редактировать на GitHub