Стилизованные компоненты в React: краткое руководство

от автора

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

Представляю вашему вниманию перевод небольшой заметки про использование стилизованных компонентов (далее — СК) в React.

Без лишних слов.

Что такое СК?

СК — это библиотека для React и React Native для создания и управления CSS.

Данное решение относится к концепции «CSS-in-JS», когда вы определяете CSS прямо в JavaScript-файле (т.е. в компоненте в случае с React).

О популярности этого решения в среде React-разработчиков свидетельствует около 8 млн скачиваний в месяц из npm и 30 тыс звезд на GitHub.

Разумеется, для знакомства со СК необходимо хотя бы в общих чертах знать React.

Преимуществами СК является следующее:

  • Это обычный CSS. Да, вы пишете CSS в JS-файле, но синтакис от этого не меняется
  • При использовании СК автоматически добавляются вендорные префиксы, обеспечивающие кроссбраузерность
  • Неиспользуемые стили также автоматически удаляются
  • Более того, автоматически генерируются названия классов компонентов, что избавляет от необходимости использования методогии типа БЭМ

Установка СК

Для использования СК нужно их сначала установить:

npm i styled-components 

Далее их нужно импортировать в каждом файле, в котором они будут использоваться:

import styled from 'styled-components' 

После этого можно с ними работать.

Создание СК

Откройте проект, над которым вы работаете, или быстро создайте его с помощью npx create-react-app app-name и откройте любой компонент, например, App.js.

Давайте добавим в него наш первый СК:

// App.js import React from 'react' import styled from 'styled-components'  // СК const Button = styled.a`     background-color: teal;     color: white;     padding: 1rem 2rem; `  const App = () => {     return (         <Button>Кнопка</Button>     ) }  export default App 

Разберем данный код:

  • Объявляем название компонента посредством const Button
  • styled предоставляет нам функционал СК
  • Обратите внимание на «a» после styled. Это HTML-тег «a». В СК можно использовать любые HTML-теги (section, h1, div и т.д.)

<Button>, возвращаемый в App, это обычный React-компонент.

В предыдущем примере мы создали СК внутри существующего компонента.

Однако это можно (и даже нужно) сделать в отдельном файле (например, в Button.js):

// Button.js import styled from 'styled-components'  const Button = styled.a`     background-color: teal;     color: white;     padding: 1rem 2rem; `  export default Button 

После этого мы можем импортировать Button как любой другой компонент:

// App.js import React from 'react' import styled from 'styled-components' // импортируем кнопку import Button from './Button'  const App = () => {     return (         <Container>             <Button>Кнопка</Button>         </Container>     ) }  export default App 

Готово.

Поздравляю, вы только что создали свой первый СК.

Использование пропсов для редактирования СК

Представьте, что у вас есть компонент Button, и вам нужно применять к нему разные стили в зависимости от назначения кнопки (primary — главная или основная, secondary — второстепенная или дополнительная, danger — опасность, предупреждение и т.д.)

Для этого можно использовать пропсы.

Рассмотрим пример.

Здесь мы рендерим две кнопки, стиль одной из который зависит от пропса:

// App.js import React from 'react' import styled from 'styled-components' import Button from './Button'  const App = () => {     return (         <>             <Button>Кнопка</Button>             <Button primary>Главная кнопка</Button>         </>     ) }  export default App 

Обратите внимание на использование сокращенного синтаксиса фрагмента (<></>).

После этого добавляем динамические стили в компонент Button:

// Button.js import styled from 'styled-components'  const Button = styled.a`     display: imline-block;     border-radius: 3px;     padding: 0.5rem 0;     margin: 0.5rem 1rem;     width: 11rem;     border: 2px solid white;     background: ${props => props.primary ? 'white' : 'palevioletred'};     color: ${props => props.primary ? 'palevioletred' : 'white'}; `  export default Button 

Здесь мы возвращаем то или иное значение CSS-свойства в зависимости от пропса.

Выражение background: ${props => props.primary? ‘white’: ‘palevioletred’} означает, что если пропс будет иметь значение true, то цвет фона будет белым, а цвет текста — palevioletred.

Такой способ можно использовать в простых случаях, однако он не подходит для случаев, когда нужно обрабатывать несколько пропсов, а также при наличии нескольких свойств, зависящих от них.

Поэтому имеет смысл импортировать { css } из styled-components:

// Button.js import styled, { css } from 'styled-components'  const Button = styled.a` display: inline-block;     border-radius: 3px;     padding: 0.5rem 0;     margin: 0.5rem 1rem;     width: 11rem;     background: transparent;     color: white;     border: 2px solid white;      ${props => props.primary && css`         background: white;         color: palevioletred;     `} `  export default Button 

Это позволяет использовать динамические стили для разных пропсов.

Например, добавим стили для danger:

// Button.js import styled, { css } from 'styled-components'  const Button = styled.a` display: inline-block;     border-radius: 3px;     padding: 0.5rem 0;     margin: 0.5rem 1rem;     width: 11rem;     background: transparent;     color: white;     border: 2px solid white;      ${props => props.primary && css`         background: white;         color: palevioletred;     `}      ${props => props.danger && css`         backround: red;         color: white;     `} `  export default Button 

Отлично.

Как сделать кнопку более отзывчивой или адаптированной?

Использование медиа-запросов

Для этого следует добавить медиа-запросы в шаблон (внутрь шаблонного или строкового литерала):

// Button.js const Button = styled.a`     display: inline-block;     border-radius: 3px;     padding: 0.5rem 0;     margin: 0.5rem 1rem;     width: 9rem;     background: transparent;     color: white;     border: 2px solid white;      @media (min-width: 768px) {         padding: 1rem 2rem;         width: 11rem;     }      @media (min-width: 1024px) {         padding: 1.5rem 2.5rem;         width: 13rem;     } `  export default Button 

Обработка псевдоселекторов

Это делается по аналогии с медиа-запросами.

Например, добавим обработку наведения курсора на кнопку (псевдоселектор hover):

// Button.js import styled from 'styled-components'  const Button = styled.a`     display: inline-block;     border-radius: 3px;     padding: 0.5rem 0;     margin: 0.5rem 1rem;     width: 9rem;     background: transparent;     color: white;     border: 2px solid white;      :hover {         border-color: green;     } `  export default Button 

Создание глобальных стилей

Основная ментальная модель React — все есть компонент.

Для этого интерфейс приложения разбивается на отдельные части, а затем эти части собираются в один файл таким образом, чтобы сохранялась возможность расширения или масштабирования приложения.

Такой подход имеет ряд преимуществ, но существует одна проблема: как использовать одинаковые стили для нескольких компонентов? Т.е. как применить глобальные стили?

Мы можем, например, захотеть следующее:

  • Установить шрифт для всего текста
  • Установить фон для всех страниц
  • Перезаписать некоторые браузерные стили (т.е. стили, устанавливаемые по умолчанию)

В СК для этого используется функция createClodabStyle.

Сначала откройте основной компонент приложения.

Таким компонентом, обычно, является App.js.

Затем импортируйте в него createClodabStyle и определите некоторые стили в компоненте GlobalStyle (вы можете назвать его как угодно):

// App.js import React from 'react' import styled, { createGlobalStyle } from 'styled-components' import { Container, Nav, Content } from '../components'  const GlobalStyle = createGlobalStyle`     body {         margin: 0;         padding: 0;         background: teal;         font-family: Open-Sans, Helvetica, Sans-Serif;     } `  const App = () => {     return (         <Container>             <Nav />             <Content />         </Container>     ) }  export default App 

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

// App.js import React from 'react' import styled, { createClodabStyle } from 'styled-components' import { Container, Nav, Content } from '../components'  const GlobalStyle = createGlobalStyle`     body {         margin: 0;         padding: 0;         background: teal;         font-family: Open-Sans, Helvetica, Sans-Serif;     } `  const App = () => {     return (         <>             <GlobalStyle />             <Container>                 <Nav />                 <Content />             </Container>         </>     ) }  export default App 

Добавление GlobalStyle в качестве узла в начало виртуального DOM является обязательным требованием для использования глобальных стилей.

Надеюсь, статья была вам полезной. Благодарю за внимание.

ссылка на оригинал статьи https://habr.com/ru/post/515454/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *