React Junior
207 subscribers
37 photos
462 links
Изучение React с нуля
加入频道
Итак, CSS-модули оказались очень простой и скучной вещью, поэтому завязываем с ними.

Подведя итог: модули - это неплохо, но не то, чтобы прям прорыв.

Из недостатков: требуются настройки для работы с ними, дополнительная сборка (интересно, это достаточно эффективно?) и конечный DOM получается довольно сложным из-за уникальных имен, но БЭМ тоже здорово перегружает верстку.

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

#стили
Styled Components

Библиотека Styled Components позволяет создавать React-компоненты сразу со стилями. Тут акцент именно на стилях, у этих компонентов нет никакой логики, только оформление.

Пример создания компонента на картинке. Для этого используется синтаксис шаблонных строк. После styled указывается имя тега, который будет корневым элементом компонента, в данном случае это кнопка button. А дальше в обратных кавычках пишется привычный CSS.

Теперь компонент Button можно использовать привычным образом внутри React-приложения.

Смотреть: https://codesandbox.io/s/styled-components-1-react-junior-kkncf?file=/src/App.js

#стили #styledcomponents #примерыкода
Передача пропсов в Styled Components

На первый взгляд похоже, что styled - это просто какая-то вариация document.createElement, которая сразу добавляет созданному элементу стили. Но это все-так компонент React, а значит, мы можем передать ему пропсы.

Чтобы свойство было динамическим (основывалось на значении пропсов), нужно оформить его как функцию. А чтобы вставить функцию в шаблонную строку, нужно использовать синтаксис интерполяции.

height: ${(props) => (props.size || 38) + "px"};


С помощью интерполяции можно вставлять не только значение свойств, но и целиком правило (имя свойства + значение), и даже несколько правил. В общем, так как стили передаются в виде строки, любой ее фрагмент можно заменить на динамическое выражение.

${props => props.border && "border-color: " + props.border};


Вообще для подобных ситуаций (когда нужно сделать динамическими целые правила), предназначена функция css из того же пакета, которая тоже является теговым шаблоном.

Да, мы используем одну функцию-тег (css) внутри другой (styled.button).

Смотреть:

https://codesandbox.io/s/styled-components-2-react-junior-6zw60?file=/src/App.js

Подробнее о теговых шаблонах на MDN

#стили #styledcomponents #примерыкода
Медиа-запросы и динамические состояния в Styled Components

Сразу же возник вопрос, как определять различные динамические состояния стилизованного компонента (ховеры, адаптив). Очень просто, прямо в шаблонной строке стилей, которую мы отдаем в функцию styled.tagName:

Смотреть: https://codesandbox.io/s/styled-components-3-react-junior-cte6s?file=/src/App.js&resolutionWidth=400&resolutionHeight=130

#стили #styledcomponents #примерыкода
Наследование в StyledComponent

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

#стили #styledcomponents
Внезапно оказалось, что styled.div/styled.a и прочие свойства функции styled - это не более чем псевдонимы. Нужный тег (или компонент) можно передать прямо в функцию styled и получить нужную шаблонную строку.

#важно #стили #styledcomponents
StyledComponents с кастомными React-компонентами

До сих пор мы создавали стилизованные компоненты только на базе обычных HTML-тегов. Оказывается, можно использовать для этого и React-компоненты.

Нужно просто передать кастомный компонент в функцию styled, и он будет использован как базовый.

Важно: внутри кастомного компонента обязательно нужно использовать проп className, иначе стили не применятся.

Смотреть: https://codesandbox.io/s/styled-components-5-react-junior-yeds8?file=/src/App.js

Вот мы ненароком и узнали, как работают styledComponents. Они генерируют уникальное имя класса, к которому и привязываются стили (похоже на CSS Модули).

#стили #styledcomponents #примерыкода #важно
Изменение тега

При создании компонента мы сразу определяем тег, который будет его представлять: styled.div или styled.button. А что делать, если одинаковые стили нужны и для кнопки, и для ссылки? Дублировать их?

К счастью, нет. Тег, к которому будут применены стили можно подменить динамически с помощью пропа as.

В него можно передать либо валидное имя тега в виде строки, либо даже имя кастомного React-компонента. Главное внутри этого компонента использовать полученный проп className, иначе стили не будут применены.

Смотреть: https://codesandbox.io/s/styled-components-4-react-junior-7xpq2?file=/src/App.js

#стили #styledcomponents #примерыкода
Глобальные стили

В каждом приложении есть глобальные стили вроде семейства шрифтов или сброса стилей. Казалось бы, их невозможно оформить в виде компонента, но у StyledComponents другое мнение.

Чтобы определить глобальные стили, нужно создать новый стилизованный компонент с помощью функции createGlobalStyle, а затем вставить его наверху проекта.

#стили #styledcomponents #примерыкода
Создание анимации с помощью StyledComponents

ДЛя создания анимаций используется теговая функция keyframes из пакета styled-components. Она принимает тот же самый CSS-код, который вы обычно помещаете в конструкцию @keyframes, а возвращает имя созданное анимации.

Это имя нужно вставить в CSS-свойство animation-name в вашем стилизованном компоненте.

#стили #styledcomponents #примерыкода
Настройка атрибутов

Так как StyledComponents - это настоящие компоненты, у них могут быть атрибуты. Некоторые из них мы устанавливаем с помощью пропсов, а другие, которые не изменяются, можно установить сразу.

Для этого предназначен метод attrs, которые принимает объект с именами и значениями нужных атрибутов.

#стили #styledcomponents #примерыкода
Первое знакомство со StyledComponents состоялось. Источником знаний выступили в основном статьи, первыми попавшиеся в поисковике. Из самых подробных (на русском):

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

Пора переходить к фундаментальным источникам: документации (англ.).

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

#ссылки #стили #styledcomponents
Пропсы и атрибуты

👉 Все пропсы, которые являются стандартными HTML-атрибутами пробрасываются до HTML-контейнера стилизованного компонента.

👉 Можно установить атрибуты прямо внутри конструктора стилизованного компонента с помощью метода attrs, который может принимать как объект, так и функцию.

👉 Если один стилизованный компонент "наследует" от другого, то стили и атрибуты наследника переопределяют стили и атрибуты родителя (логично).

https://codesandbox.io/s/styled-components-5-react-junior-l4cn6?file=/src/App.js

#стили #styledcomponents #документация
Заинтересовал этот фрагмент. Что тут особенного:

1. В качестве селектора можно использовать не только &, который, как и в Scss, указывает на сам элемент, но и &&.

После обработки & заменяется на уникальное имя класса, сгенерированное для компонента, например, на .srTxsd.

А вместо && соответственно будет .srTxsd.srTxsd. То есть это нужно для повышения специфичности селектора.

2. Если стилизованный компонент привести к строке (метод toString), то мы получим его селектор - .srTxsd, который можно использовать, например, в глобальных стилях.

#стили #styledcomponents #документация
Анимации по требованию

Еще один любопытный момент, начиная с 4 версии анимации, созданные функцией keyframes загружаются динамически, поэтому мы не можем использовать их с помощью обычной интерполяции. Например, чтобы сохранить отдельно сниппет стиля.

Чтобы все сработало, нужно использовать именно теговую строку (функция css).

#стили #styledcomponents #документация
Плюсы и минусы StyledComponents

👍 Автоматическое выделение критического CSS и загрузка на страницу только нужных стилей.
👍 Автоматическое добавление вендорных префиксов.
👍 Нет коллизий имен, нельзя сделать опечатку в имени класса и сломать оформление.
👍 Не нужно соглашение об именах.
👍 Очевидно, какие стили какому компоненту принадлежат, они все в одном месте, их проще редактировать, все лишнее удаляется.
👍 Можно создавать динамические стили, основанные на данных из JavaScript.
👍 Есть наследование.
👍 Компонентный подход, в духе React.
👍 Используется обычный понятный SCSS-подобный синтаксис.

👎 Сильно раздувается JS-файл.
👎 Браузер не может загрузить стили заранее, так как они находятся в JS-файле.

На первый взгляд, конечно, инструмент кажется очень интересным, но вот это раздувание js-кода стилями очень печалит. А если выделять стилизованные компоненты в отдельный файл, то мы как будто вернемся к тому, с чего начинали...

#стили #styledcomponents
Темы оформления

В Styled Components есть поддержка тем. Можно определить набор значений (цвета, размеры и пр.) и использовать их по всему проекту.

Мы уже говорили про контекст в React - глобальное пространство имен. Там было довольно сложно, нужно было сделать несколько шагов, чтобы создать и использовать контекст, в Styled Components все уже настроено.

Чтобы тема была доступна в любом компоненте, нужно использовать провайдер - компонент ThemeProvider. Ему нужно передать объект темы (в проп theme). После этого тема будет доступна во всех дочерних компонентах провайдера (также в props.theme).

Смотреть: https://codesandbox.io/s/styled-component-theming-react-junior-txvw1?file=/src/App.js

#стили #styledcomponents #документация #примерыкода
Темы оформления

Тема может быть не только объектом, но и функцией (которая должна вернуть объект темы). Такая функция в качестве аргумента получает родительскую тему (из родительского ThemeProvider) и может ее изменить:

https://codesandbox.io/s/styledcomponents-theming-2-react-junior-rt8ye?file=/src/App.js

#стили #styledcomponents #документация #примерыкода
Использование тем вне стилизованных компонентов

Когда мы объявляем тему в ThemeProvider, то все стилизованные компоненты внутри него автоматически получают эту тему в проп theme. А что делать с обычными (не styled) компонентами? Они ведь тоже могли бы использовать эту тему.

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

https://codesandbox.io/s/styled-components-theming-3-react-junior-32cis?file=/src/App.js

1. Хук useContext

Библиотека styled-components предоставляет переменную ThemeContext, в которой находится нужный контекст.

2. Компонент высшего порядка withTheme.

Функция withTheme получает тему из провайдера и добавляет нашему обычному компоненту проп theme.

#стили #styledcomponents #примерыкода #документация