Работа с CSS модулями в React: лучшие практики и примеры
месяц назад·2 мин. на чтение
В этой статье мы рассмотрим лучшие практики работы с CSS модулями в React и представим примеры их использования.
CSS модули - это одно из самых популярных решений для организации стилей в React-приложениях. Они позволяют изолировать стили для каждого компонента, что упрощает их поддержку и разработку. В этой статье мы рассмотрим лучшие практики и примеры работы с CSS модулями для функциональных компонентов.
Именование классов и файлов
CSS модули позволяют автоматически генерировать уникальные имена классов для каждого компонента. Чтобы сделать код более понятным и поддерживаемым, рекомендуется использовать осмысленные имена классов и файлов, отражающие их назначение. Например, если у вас есть компонентButton
, вы можете назвать его стилевой файл Button.module.css
.
Использование локальных и глобальных стилей
CSS модули позволяют определить локальные стили для конкретного компонента, а также использовать глобальные стили для всего приложения. Такой подход позволяет создавать переиспользуемые стили и управлять ими более эффективно. Например, вы можете определить общие стили для кнопок в глобальном файле стилей, а затем использовать локальные стили для конкретного компонентаButton
, если необходимы дополнительные или измененные стили.
Подключение CSS модулей в React-компонентах
Чтобы использовать CSS модули в функциональных компонентах React, вы можете импортировать стили с помощью конструкцииimport
и применить их к элементам JSX с помощью атрибута className
. Например, если у вас есть стилевой файл Button.module.css
c классом button
, вы можете импортировать его и применить к кнопке следующим образом:
import React from "react"; import styles from "./Button.module.css"; const Button = () => { return <button className={styles.button}>Click me</button>; }; export default Button;
Использование динамических классов
CSS модули также поддерживают динамическое добавление классов в зависимости от определенных условий. Например, если вы хотите добавить классactive
к кнопке, если она находится в активном состоянии, вы можете использовать стандартный оператор if
/else
внутри функционального компонента для определения значения атрибута className
:
import React, { useState } from "react"; import styles from "./Button.module.css"; const Button = () => { const [isActive, setIsActive] = useState(false); const handleButtonClick = () => { setIsActive(!isActive); }; return ( <button className={`${styles.button} ${isActive ? styles.active : ""}`} onClick={handleButtonClick} > Click me </button> ); }; export default Button;
Наследование стилей
CSS модули позволяют наследовать стили других классов, что упрощает повторное использование существующих стилей. Например, вы можете определить базовый классbase
с общими стилями для всех кнопок, а затем создать новый класс button
с дополнительными стилями:
Это позволяет создавать более модульные и гибкие стили, а также упрощает их поддержку и изменение. В заключение, работа с CSS модулями в React выгодна для разработки функциональных компонентов, так как позволяет организовать и изолировать стили для каждого компонента. Надеюсь, эти лучшие практики и примеры помогут вам эффективно использовать CSS модули в ваших проектах./* Button.module.css */ .base { /* общие стили для всех кнопок */ } .button { composes: base; /* дополнительные стили для кнопок */ }
React паттерн headless component
месяц назад·2 мин. на чтение
Рассмотрим использование паттерна headless component для создания модульных и гибких компонентов в React приложениях.
Разработка программного обеспечения — это непрерывный процесс. Самой большой проблемой в этом процессе является удобство сопровождения. Когда новые функции и улучшения начинают добавляться, это приводит к добавлению большего количества кода.
В этой статье мы рассмотрим простой паттерн в React, который позволяет создавать компоненты, ориентированные на будущее. Цель состоит в том, чтобы эти компоненты легко адаптировались к будущим изменениям, сохраняя при этом бизнес-логику отдельно от кода пользовательского интерфейса.
Выше приведен очень простой пример компонента. Представьте себе возможность, когда один и тот же шаблон интегрируется с более сложными приложениями. Шаблон headless component является чрезвычайно мощным, когда речь идет о создании перспективных компонентов с высокой степенью расширяемости.
Как это работает?
Суть этого шаблона заключается в том, чтобы отделить бизнес-логику от UI части самого компонента. Когда в будущем потребуется обновить пользовательский интерфейс, это можно сделать, не затрагивая код бизнес-логики. Паттерн, который мы собираемся использовать, называется headless component. В этом шаблоне компонент реализован в виде хуков React. Этот компонент отвечает за логику и управление состоянием. Headless-компонент ничего не знает о пользовательском интерфейсе. Создается отдельный компонент, который отвечает только за пользовательский интерфейс. Паттерн используется многими популярными библиотеками компонентов React, такими как: DownShift, React Table и т.д.Ваш первый headless компонент
Начнем с написания первого React компонента с использованием этого шаблона. Ниже приведен пример компонента dropdown:Давайте интегрируем наш headless-компонент с компонентом, отвечающим за обработку пользовательского интерфейса:const useDropdown = (items: Item[]) => { // состояние const [selectedIndex, setSelectedIndex] = useState<number>(-1); const [isOpen, setIsOpen] = useState(false); const [selectedItem, setSelectedItem] = useState<Item | null>(null); // функция возвращающая aria-атрибуты для UI const getAriaAttributes = () => ({ role: "combobox", "aria-expanded": isOpen, "aria-activedescendant": selectedItem ? selectedItem.text : undefined, }); const handleKeyDown = (e: React.KeyboardEvent) => { // реализация на основе switch-case }; const toggleDropdown = () => setIsOpen((isOpen) => !isOpen); return { isOpen, toggleDropdown, handleKeyDown, selectedItem, setSelectedItem, selectedIndex, }; };
const Dropdown = ({ items }: DropdownProps) => { const { isOpen, selectedItem, selectedIndex, toggleDropdown, handleKeyDown, setSelectedItem, } = useDropdown(items); return ( <div className="dropdown" onKeyDown={handleKeyDown}> <Trigger onClick={toggleDropdown} label={selectedItem ? selectedItem.text : "Select an item..."} /> {isOpen && ( <DropdownMenu items={items} onItemClick={setSelectedItem} selectedIndex={selectedIndex} /> )} </div> ); };