Хотите заказать веб-сайт? Связаться с нами

Styled Components в React: полное руководство

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

Styled Components в React: полное руководство

Что такое styled-components и зачем они нужны

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

Такой подход решает сразу несколько проблем, знакомых каждому фронтенд-разработчику.

Во-первых, исчезает риск случайного совпадения имён классов — библиотека автоматически генерирует уникальные имена.

Во-вторых, стили компонента живут рядом с самим компонентом, а не в отдельном CSS-файле, что упрощает навигацию по проекту.

В-третьих, неиспользуемый CSS автоматически удаляется: если компонент не рендерится, его стили не попадают в итоговый бандл.

Другие преимущества

  1. Динамическая стилизация на основе пропсов
  2. Поддержка тем оформления через ThemeProvider
  3. Автоматическая расстановка вендорных префиксов
  4. Возможность наследовать и комбинировать стили компонентов

Дальше на практике посмотрим, как всё это работает.

Установка и первый стилизованный компонент

Для начала работы установите библиотеку через пакетный менеджер:

npm install styled-components
# или
yarn add styled-components

Если вы используете styled-components версии ниже 6, дополнительно понадобится пакет @types/styled-components для корректной работы с TypeScript. Начиная с версии 6 типы уже встроены в саму библиотеку.

Создать стилизованный компонент можно с помощью функции styled, вызывая метод, соответствующий нужному HTML-тегу, — например, styled.button или styled.div. Внутри тегированной шаблонной строки пишется обычный CSS, включая вложенные селекторы и псевдоклассы:

import styled from 'styled-components';
 
const Button = styled.button`
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  background-color: #326ec1;
  color: white;
  font-size: 16px;
  cursor: pointer;
 
  &:hover {
    background-color: #274f8f;
  }
`;
 
function App() {
  return <Button>Нажми меня</Button>;
}

Компонент Button из примера выше — это полноценный React-компонент. Он принимает те же пропсы, что и обычный button, и рендерит его в DOM с автоматически сгенерированным классом.

Динамические стили через пропсы

Одно из главных преимуществ styled-components — возможность менять стили в зависимости от пропсов компонента. Внутри шаблонной строки можно использовать функции, которые получают пропсы и возвращают нужное значение:

interface ButtonProps {
  variant?: 'primary' | 'secondary';
}
 
const StyledButton = styled.button<ButtonProps>`
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  color: white;
  background-color: ${({ variant }) =>
    variant === 'secondary' ? '#6c757d' : '#326ec1'};
`;
 
function App() {
  return (
    <>
      <StyledButton variant="primary">Основная</StyledButton>
      <StyledButton variant="secondary">Вторичная</StyledButton>
    </>
  );
}

В этом примере значение свойства background-color вычисляется на основе пропса variant. Такой подход избавляет от необходимости писать дополнительные CSS-классы для каждого состояния компонента.

Не создавайте styled-компоненты внутри тела функционального компонента или прямо в JSX на каждый рендер — определяйте их на уровне модуля, вне компонента. В противном случае React будет создавать новый компонент и новый CSS-класс при каждом рендере, что негативно скажется на производительности и приведёт к накоплению лишних стилей в DOM.

Наследование и композиция стилей

styled-components поддерживают наследование стилей: можно взять уже существующий стилизованный компонент и дополнить его новыми правилами с помощью styled(Component):

const Button = styled.button`
  padding: 12px 24px;
  border-radius: 8px;
  border: none;
`;
 
const DangerButton = styled(Button)`
  background-color: #dc3545;
  color: white;
`;
 
function App() {
  return <DangerButton as="a" href="/delete">Удалить</DangerButton>;
}

Обратите внимание на проп as — он позволяет отрендерить стилизованный компонент с другим HTML-тегом, сохранив при этом все стили. В примере выше DangerButton рендерится как ссылка a, а не как button, но выглядит так же.

Ещё один полезный инструмент — метод .attrs(), который позволяет задавать HTML-атрибуты компонента по умолчанию, например type="submit" для кнопки формы или placeholder для поля ввода, не засоряя JSX лишними пропсами.

Темизация с ThemeProvider

Когда в проекте нужно поддерживать несколько цветовых схем или просто держать все значения дизайна (цвета, отступы, шрифты) в одном месте, на помощь приходит ThemeProvider. Он оборачивает часть дерева компонентов и передаёт объект темы через React Context — любой styled-компонент внутри получает доступ к теме через специальный проп theme:

import { ThemeProvider } from 'styled-components';
 
const theme = {
  colors: {
    primary: '#326ec1',
    accent: '#ffb131',
  },
};
 
const Title = styled.h1`
  color: ${({ theme }) => theme.colors.primary};
`;
 
function App() {
  return (
    <ThemeProvider theme={theme}>
      <Title>Заголовок страницы</Title>
    </ThemeProvider>
  );
}

Внутри шаблонной строки любого styled-компонента доступен параметр theme, из которого можно брать значения — цвета, размеры шрифтов, отступы. Это особенно удобно для реализации переключения между светлой и тёмной темой: достаточно поменять объект, переданный в ThemeProvider, и все компоненты автоматически обновят стили.

Глобальные стили с createGlobalStyle

Помимо стилей отдельных компонентов, часто нужны глобальные правила — сброс отступов у body, подключение шрифта, базовые настройки box-sizing. Для этого styled-components предоставляет функцию createGlobalStyle:

import { createGlobalStyle } from 'styled-components';
 
const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    font-family: sans-serif;
  }
`;
 
function App() {
  return (
    <>
      <GlobalStyle />
      <Title>Приложение</Title>
    </>
  );
}

Компонент, созданный с помощью createGlobalStyle, не оборачивает разметку и не принимает children — его достаточно один раз отрендерить в корне приложения, и описанные в нём стили применятся ко всему документу.

Итоги

В этом уроке мы разобрались, что такое styled-components и какую проблему решает подход CSS-in-JS. Вы научились создавать стилизованные компоненты, менять их внешний вид с помощью пропсов, наследовать и комбинировать стили через styled(Component) и проп as, а также настраивать единую тему оформления с помощью ThemeProvider и задавать глобальные стили через createGlobalStyle.

В следующем уроке познакомимся с Emotion — ещё одной популярной библиотекой для CSS-in-JS, сравним её со styled-components и разберём, чем отличаются их подходы к API и производительности.

Теги: