5 подходов к стилизации React-компонентов на примере одного приложения



    Доброго времени суток, друзья!

    Сегодня я хочу поговорить с вами о стилизации в 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

    Как всегда, буду рад любой форме обратной связи.

    Благодарю за внимание и хорошего дня.

    Similar posts

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 6

      +2
      Мужик, астанавись! У тебя почти сотня хреновых статей про js/реакт. Кому они нужны?
      За то время что их клепаешь уже мог бы разобраться в чем-нибудь нормально и написать одну качественную.
        +1
        А почему CSS-в-JS лучше остальных подходов?
          0
          Разумеется ни чем не лучше. Это просто абсолютно другой подход вот и всё.

          Тут как бы смехотворный аргумент
          На мой взгляд, лучшим решением является последний подход, т.е. CSS-в-JS. Он выглядит самым логичным с точки зрения описания структуры (разметки), внешнего вида (стилей) и логики (скрипта) компонента в одном файле — получаем нечто вроде Все-в-JS.
            +1
            Спасибо.
            +1

            Не лучше. Как обычно, есть разные trade-off.
            Главные плюсы — упорядоченность через код (можно подключить линтер, TS, и всё вот это) и тьюринг-полный язык действий над стилями.
            Главные минусы — вендор-лок (в лучшем случае "ванильный" css можно будет отдать внутрь css-in-js решения как портянку plaintext, см. emotion, в худшем, как в styled-components, нельзя будет и этого) и всегда добавочные тормоза в обработке этого всего (впрочем, не всегда это имеет значение и вообще можно увидеть даже замерами).

              0
              Спасибо.

          Only users with full accounts can post comments. Log in, please.