Интерактивные элементы 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
// });
Вам ответят команда поддержки Хекслета или другие студенты.
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Загляните в раздел «Обсуждение»:
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт