Доброго времени суток, друзья!
Сегодня я хочу поговорить с вами о стилизации в React.
Почему данный вопрос является актуальным? Почему в React существуют разные подходы к работе со стилями?
Когда дело касается разметки (HTML), то React предоставляет в наше распоряжение JSX (JavaScript и XML). JSX позволяет писать разметку в JS-файлах данную технику можно назвать HTML-в-JS.
Однако, когда речь идет о стилях, то React не предоставляет каких-либо специальных инструментов (JSC?). Поэтому каждый разработчик волен выбирать такие инструменты по своему вкусу.
Всего можно выделить 5 подходов к стилизации React-компонентов:
- Глобальные стили все стили содержатся в одном файле (например, index.css)
- Нативные CSS-модули для каждого компонента создается отдельный файл со стилями (например, в директории css); затем эти файлы импортируются в главный CSS-файл (тот же index.css) с помощью директивы "@import"
- Реактивные CSS-модули (данная техника используется не только в React-проектах; реактивными я назвал их потому, что библиотека css-modules в настоящее время интегрирована в React, т.е. не требует отдельной установки, по крайней мере, при использовании create-react-app) для каждого компонента создается файл Component.module.css, где Component название соответствующего компонента (обычно, такой файл размещается рядом с компонентом); затем стили импортируются в JS-файл в виде объекта, свойства которого соответствуют селекторам класса (например: import styles from './Button.module.css'; <button style={styles.button}>Нажми на меня</button>)
- Встроенные (инлайновые) стили элементы стилизуются с помощью атрибутов style со значениями в виде объектов со стилями (например, <button style={{ borderRadius: '6px'; } }>Нажми на меня</button>)
- CSS-в-JS библиотеки, позволяющие писать CSS в JS-файлах; одной из таких библиотек является styled-components: import styled from 'styled-components'; const Button = styled`какой-то css`; <Button>Нажми на меня</Button>
На мой взгляд, лучшим решением является последний подход, т.е. CSS-в-JS. Он выглядит самым логичным с точки зрения описания структуры (разметки), внешнего вида (стилей) и логики (скрипта) компонента в одном файле получаем нечто вроде Все-в-JS.
Шпаргалку по использованию библиотеки styled-components можно найти здесь. Возможно, вам также интересно будет взглянуть на шпаргалку по хукам.
Ну, а худшим подходом, по моему мнению, являются встроенные стили. Стоит, однако, отметить, что определение объектов со стилями перед определением компонента и последующее использование этих объектов напоминает CSS-в-JS, но остаются camelCase-стиль, атрибуты style и сами встроенные стили, которые затрудняют инспектирование DOM.
Предлагаю вашему вниманию простое приложение-счетчик, реализованное на React, в котором последовательно используются все названные подходы к стилизации (за исключением встроенных стилей).
Исходный код GitHub.
Песочница:
Выглядит приложение так:
Приложение состоит из трех компонентов: Title заголовок, Counter значение счетчика и информация о том, каким является число: положительным или отрицательным, четным или нечетным, Control панель управления, позволяющая увеличивать, уменьшать и сбрасывать значение счетчика.
Структура проекта следующая:
|--public |--index.html|--src |--components |--Control |--Control.js |--Control.module.css |--package.json |--styles.js |--Counter |--Counter.js |--Control.module.css |--package.json |--styles.js |--Title |--Title.js |--Title.module.css |--package.json |--index.js |--css |--control.css |--counter.css |--title.css |--App.js |--global.css |--index.js |--nativeModules.css |--reactModules.css...
Пройдемся по некоторым файлам, находящимся в директории src:
- index.js входная точка JavaScript (в терминологии бандлеров), где импортируются глобальные стили и рендерится компонент App
- App.js основной компонент, где импортируются и объединяются компоненты Control, Counter и Title
- global.css глобальные стили, т.е. стили всех компонентов в одном файле
- nativeModules.css файл, где импортируются и объединяются нативные CSS-модули из директории css (control.css, counter.css и title.css)
- reactModules.css глобальные стили для реактивных CSS-модулей
- components/Control/Control.js три реализации компонента Control (с глобальными стилями/нативными CSS-модулями, c реактивными CSS-модулями и стилизованными компонентами), а также пример объекта со встроенными стилями
- components/Control/Control.module.css реактивный CSS-модуль для компонента Control
- components/Control/styles.js стилизованные компоненты для компонента Control (когда стилизованных компонентов много, я предпочитаю выносить их в отдельный файл)
- components/Control/package.json файл с main: "./Control", облегчающий импорт компонента (вместо import Control from './Control/Control' можно использовать import Control from './Control'
- components/index.js повторный экспорт, позволяющий разом импортировать все компоненты в App.js
Как всегда, буду рад любой форме обратной связи.
Благодарю за внимание и хорошего дня.