Как написать более удобочитаемые стилизованные компоненты с функциями более высокого порядка.
Если вы когда-либо использовали styled-components, вы, скорее всего, часто использовали вызовы функций для доступа к своим props следующим образом:
const StyledLink = styled.a` color: ${props => props.color}; `;
Использовать props для определения поведения стиля - это здорово! Это кажется более естественным и наглядным, чем объединение нескольких классов CSS друг с другом. Кроме того, в сочетании с TypeScript вы можете добавить возможность обнаружения параметров стиля для ваших компонентов. Но есть случай, когда использование функций для интерполяции вашего CSS может стать действительно беспорядочным и нечитаемым: тематика.
Возьмем, к примеру, объект темы material-ui. Доступ к значениям более сложного объекта темы может привести к следующему:
const MyBox = styled.div` background-color: ${props => props.theme.palette.primaryColor.main}; color: ${props => props.theme.palette.primaryColor.contrastText}; padding: ${props => props.theme.spacing(2)} `;
С трудом читаете это? Я тоже! Кроме того, когда дело доходит до сканирования кода, это блокировщик, так как вам нужно останавливаться каждый раз, чтобы выяснить, к какому значению здесь на самом деле осуществляется доступ.
Здесь есть несколько проблем:
- При чтении функций вы ожидаете, что они будут потенциально более сложными, чем просто доступ к значениям.
- Доступ к глубоко вложенным объектам приводит к появлению длинных строк и стен текста.
- При просмотре ключевого слова props вы думаете об использовании свойств компонентов, а не о доступе к контексту темы.
- Стрелочные функции могут добавить много визуального беспорядка.
Многие из этих проблем можно решить с помощью функций высшего порядка.
Вместо того, чтобы каждый раз писать функции интерполяции, мы пишем абстрактные функции для часто выполняемых вещей, таких как доступ к цвету или интервалу. А из-за повторяющегося доступа к значениям темы это даже сэкономит вам некоторое время на написание стилей.
Давайте посмотрим, как может выглядеть приведенный выше пример с использованием функций высшего порядка.
const MyBox = styled.div` background-color: ${color('primary')}; color: ${color('primary', 'contrastText')}; padding: ${spacing(2)} `;
Легче читать и сканировать, не так ли?
Давайте реализуем функцию c olor:
const color = (variant, type = 'main') => props => props.theme.palette[variant][type];
Кроме того, вы можете создать такие функции быстрого доступа:
const primaryColor = type => color('primary', type); const secondaryColor = type => color('secondary', type); const contrastTextColor = (variant) => color(variant, 'contrastText');
Но вам не нужно останавливаться на достигнутом, вы даже можете создать что-то вроде styled-system внутри более сложных стилизованных компонентов. Это очень удобно, если вы хотите объединить более 4 или 5 различных параметров стиля (в противном случае ваш JSX стал бы менее читабельным при использовании styled-system).
const MyBox = styled.div` ${mx(2)}; ${mt(1)}; ${mb(3)}; ${shadow(2)}; display: flex; justify-content: space-between; `;
Преимущество использования чего-то подобного в том, что вы можете комбинировать более сложные стили вместе с такими значениями системы дизайна, как интервалы, тени или цвета. Написание этого в такой системе, как styled-system или @ material-ui / system, добавляет много шума в ваш настоящий JSX.
<Box mx={2} mt={1} mb={3} shadow={2} display="flex" justifyContent="space-between"> // ... </Box>
Также это сокращает время написания общих имен свойств css в сотни раз.
Функции полей, реализованные в теме material-ui, могут выглядеть примерно так:
Заключение
Функции высшего порядка дают вам множество творческих возможностей для написания вспомогательных функций, которые повышают удобочитаемость и возможности сканирования, сокращают время кодирования и в сочетании с описательным именованием также помогают другим лучше понять ваши стилизованные компоненты.
Каков ваш опыт работы с функциями высшего порядка в сочетании с styled-components? у вас есть вопросы? Или у вас есть еще несколько удобных вариантов использования для этого? Поделитесь со мной своими мыслями, мне интересно!
P.S .: В настоящее время мы создаем сервис для просмотра визуальных компонентов в запросах на извлечение GitHub. Таким образом, вы можете быстро показать новые и измененные компоненты дизайнерам, чтобы они могли дать обратную связь даже до того, как ваш запрос на слияние будет объединен. Если вам интересно, посетите наш сайт www.bojagi.io. Вы можете добавить себя в список ожидания бета-тестирования и сразу же приступить к работе.