Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Обработка имён классов JS: React

Интерактивные элементы UI имеют более одного состояния отображения. Например, модальное окно может быть открыто или закрыто, а переключатель включён или выключен. Общепринято менять эти состояния классами.

Работая напрямую с DOM, можно использовать classList, который содержит удобные методы для добавления и удаления классов. В React из коробки нет никаких удобств. Свойство className — это всего лишь строка, а строки неудобны для обработки.

class Button extends React.Component {
  render () {
    const { isPressed, isHovered, label } = this.props;
    let btnClass = 'btn';
    if (isPressed) {
      // Приходится конкатенировать классы
      btnClass += ' btn-pressed';
    } else if (isHovered) {
      btnClass += ' btn-over';
    }
    return <button className={btnClass}>{label}</button>;
  }
};

Для решения этой задачи создатели React рекомендуют использовать пакет classnames. Принцип его работы прост: вместо манипулирования строчкой напрямую, нужно сформировать правильный объект, который уже будет преобразован в строку.

import cn from 'classnames';

class Button extends React.Component {
  render () {
    const { isPressed, isHovered, label } = this.props;
    // значение это true или false. Если значение true, то класс будет включен, если false – то нет
    // 'btn' это класс который будет подставлен в любом случае
    const btnClass = cn('btn', {
      'btn-pressed': isPressed,
      'btn-over': !isPressed && isHovered,
    });
    return <button className={btnClass}>{label}</button>;
  }
};

Подставим конкретные значения:

const btnClass = cn('btn', {
  'btn-pressed': false,
  'btn-over': true,
});

console.log(btnClass); // 'btn btn-over'

Функция cn() устроена так, что она принимает на вход любое количество аргументов. Если аргумент имеет строковой тип, то он считается обязательным классом. Если это объект – то тогда работает логика описанная выше.

const btnClass = cn('btn', 'another-class', {
  'btn-pressed': isPressed,
  'btn-over': !isPressed && isHovered,
});

Обязательные классы можно задавать и в самом объекте:

const btnClass = cn({
  'btn something-else': true
  'btn-pressed': isPressed,
  'btn-over': !isPressed && isHovered,
});

Иногда имя класса генерируется динамически, тогда можно использовать следующий код:

const buttonType = 'primary';
const btnClass = cn('btn', `btn-${buttonType}`);
console.log(btnClass); // 'btn btn-primary'
// Или что то же самое
// const btnClass = cn('btn', {
//   [`btn-${buttonType}`]: true
// });

Дополнительные материалы

  1. classnames (документация)

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов для веб-приложений
6 октября 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
6 октября 16 месяцев

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и соглашаетесь с «Условиями использования»