Как использовать стилизованные компоненты в React

Стилизованные компоненты – это инструмент CSS-in-JS, которые устраняют разрыв между компонентами и стилем, предлагая множество функций, которые помогут вам начать работу с компонентами стилей функциональным и многократно используемым способом. В этой статье вы узнаете основы стилизованных компонентов и научитесь правильно применять их в ваших приложениях React. 

В основе CSS лежит возможность настройки таргетинга на любой элемент HTML – глобально – независимо от его положения в дереве DOM. Это может быть помехой при использовании с компонентами, потому что компоненты в разумной степени требуют размещения (т. е. сохранения ресурсов, таких как состояния и стили) ближе к тому месту, где они используются (локализации).

В React, стилизованные компоненты – это «визуальные примитивы для компонентов», и их цель – дать нам гибкий способ стилизации компонентов. Результатом является тесная связь между компонентами и их стилями.

Почему стилизованные компоненты

Помимо помощи в выборе стилей, стилизованные компоненты включают в себя следующие функции:

  • Автоматическое добавление префиксов поставщика: вы можете использовать стандартные свойства CSS, а стилизованные компоненты будут добавлять префиксы поставщиков, если они необходимы.
  • Уникальные имена классов: стилизованные компоненты не зависят друг от друга, и вам не нужно беспокоиться об их именах, потому что библиотека обрабатывает это за вас.
  • Устранение мертвых стилей: стилизованные компоненты удаляют неиспользуемые стили, даже если они объявлены в вашем коде.

Установка

Установить стилизованные компоненты легко. Вы можете сделать это через CDN или с помощью диспетчера пакетов, такого как Yarn:
yarn add styled-components

Начало работы

Возможно, первое, что вы заметите в стилизованных компонентах, – это их синтаксис, который может показаться устрашающим, если вы не понимаете магию стилизованных компонентов. Стилизованные компоненты используют литералы шаблонов JavaScript для преодоления разрыва между компонентами и стилями. Итак, когда вы создаете стилизованный компонент, на самом деле вы создаете компонент React со стилями. Выглядит это так:

import styled from "styled-components";

// Styled component named StyledButton
const StyledButton = styled.button`
  background-color: black;
  font-size: 32px;
  color: white;
`;

function Component() {
  // Use it like any other component.
  return <StyledButton> Login </StyledButton>;
}

Вот StyledButton стилизованный компонент, и он будет отображаться как кнопка HTML с содержащимися стилями. styled – это внутренний служебный метод, который преобразует стили из JavaScript в реальный CSS.

В необработанном HTML и CSS у нас было бы это:

button {
  background-color: black;
  font-size: 32px;
  color: white;
}

<button> Login </button>

Адаптация на основе реквизита

Стилизованные компоненты функциональны, поэтому мы можем легко стилизовать элементы динамически. Предположим, у нас есть два типа кнопок на нашей странице: одна с черным фоном, а другая синяя. Нам не нужно создавать для них два стилизованных компонента; мы можем адаптировать их стиль в зависимости от их реквизита.

import styled from "styled-components";

const StyledButton = styled.button`
  min-width: 200px;
  border: none;
  font-size: 18px;
  padding: 7px 10px;
  /* The resulting background color will be based on the bg props. */
  background-color: ${props => props.bg === "black" ? "black" : "blue";
`;

function Profile() {
  return (
    <div>
      <StyledButton bg="black">Button A</StyledButton>
      <StyledButton bg="blue">Button B</StyledButton>
    </div>
  )
}

Поскольку StyledButton это компонент React, который принимает реквизиты, мы можем назначить другой цвет фона в зависимости от существования или значения bg свойства.

Однако вы заметите, что мы не добавили нашей кнопке type. Давайте сделаем это:

function Profile() {
  return (
    <>
      <StyledButton bg="black" type="button">
        Button A
      </StyledButton>
      <StyledButton bg="blue" type="submit" onClick={() => alert("clicked")}>
        Button B
      </StyledButton>
    </>
  );
}

Стилизованные компоненты могут различаться между типами реквизита, которые они получают. Они знают, что type это атрибут HTML, поэтому они фактически выполняют рендеринг <button type="button">Button A</button>, используя bg опору в своей собственной обработке. 

Говоря об атрибутах, расширенный синтаксис позволяет нам управлять реквизитами с помощью конструктора attrs :

const StyledContainer = styled.section.attrs((props) => ({
  width: props.width || "100%",
  hasPadding: props.hasPadding || false,
}))`
  --container-padding: 20px;
  width: ${(props) => props.width}; // Falls back to 100%
  padding: ${(props) =>
    (props.hasPadding && "var(--container-padding)") || "none"};
`;

Обратите внимание, что нам не нужен троичный элемент при установке ширины, это потому, что мы уже установили для него значение по умолчанию с width: props.width || "100%".

Ответить