Как использовать styled-components без литералов шаблона

1656668892 kak ispolzovat styled components bez literalov shablona

Джейк Уизлер

-bmCEVFtIS2uUfrccPhudu7cIVRtoBywTexv
о, ты хищник, а

Если вы использовали styled-components в прошлом вы, вероятно, видели стандартный (согласно документации) способ объявления компонента с помощью styled API:

import styled from 'styled-components'
const Button = styled.button`  background: palevioletred;   color: #fff;`

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

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

const Button = styled('button')([],  'background: palevioletred',  'color: #fff')

Это интересно, и я хотел бы это изучить.

Как это работает?

Если вы прочтете публикацию Макса Штойбера «Очарование по стилизованным компонентам», он подробно рассказывает о внутренней работе своей популярной библиотеки CSS. The styled API of styled-components полагается на литералы шаблона с тэгами, и это, вероятно, то, как вы увидите, как его использует большинство людей.

Но это не единственный способ объявить компоненты с помощью styled API. Это ключевая идея этой публикации, но сейчас она может показаться непонятной. Итак, чтобы ответить на вопрос, как это работает?сначала нам нужно немного погрузиться в литералы шаблона с тэгами.

Шаблон письма с тегами

Давайте сделаем важное различие между буквами шаблона и буквами шаблона с тегами. Какая разница?

Литералы шаблона в соответствии с Mozilla:

«строчные литералы, разрешающие встроенные выражения».

Эти строки могут быть многострочными:

const multiLiner = `  Look Ma,  2 lines!`

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

const food = 'burger'
const str="Mmmm! That is a tasty ${food}!
O4ksRAAXJa5q98ps0eX3yfffNUlPzyDX6TEF
криминальное чтиво ya dig

${ This here } является интерполяцией. Воспринимайте их как заполнители для выражений JavaScript.

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

// regular function call
myFunc(1, 2, 3)
// tag function call
myFunc`1, 2, 3`

Вторая версия myFunc выше известен как a функция тегов.

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

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

const logArgs = (...args) => console.log(...args)

Вышеприведенная функция использует распространение… отдых операторы. Аргументы функции собираются в единый массив с названием args используя …args синтаксис. Это называется отдых. Вы можете думать об этом как о «сборе остальных» аргументов в массив с именем args. Это полезно, когда вы не знаете сколько аргументов может иметь функция.

Его брат, распространениевозникает, когда мы записываем аргументы на консоль с помощью console.log(...args). Мы буквально «распространяем» содержимое args массив.

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

logArgs(1, 2, 3)
// -> 1
// -> 2
// -> 3
logArgs`1, 2, 3`
// -> ["1, 2, 3"]

Обычный вызов функции делает то, что мы ожидаем. Это распространяет args разбивает массив на отдельные значения и регистрирует каждый из них на консоли.

Звонок logArgs использование литерала шаблона с тэгами, с другой стороны, регистрирует массив. Это наш первый урок:

Литералы шаблона с тегами передают массив строковых значений в качестве первого аргумента функции тега.

Вещи становятся еще более интересными, когда мы включаем интерполяции:

const food = "burger'
logArgs`Mmmm! That is a tasty ${food}!`
// -> ["Mmmm!  That is a tasty ", "!"]
// -> "burger"

logArgs по-прежнему выводит массив строчных значений как свой первый аргумент, но если тегированный литерал шаблона имеет интерполяцию, то выражение внутри интерполирования передается как следующий аргумент.

Что происходит, когда существует несколько интерполяций?

const food = 'burger'
const adj = 'tasty'
logArgs`Mmmm! That is a ${adj} ${food}!`
// -> ["Mmmm!  That is a ", " ", "!"]
// -> "tasty"
// -> "burger"

Мы можем иметь сколь угодно интерполяций, и каждая из них будет передана соответственно. Это второй урок:

Если в литералах шаблона с тегами существуют интерполяции, содержащие их выражения передаются как дополнительные аргументы функции тега.

Давайте посмотрим, как литералы шаблона с тэгами обрабатывают интерполированные функции:

logArgs`Mmmm! That is a tasty ${() => 'burger'}`
// -> ["Mmmm!  That is a tasty", "!"]
// -> () => "burger"

Сама функция включается в качестве аргумента. Это суть styled-components. Захватив такую ​​функцию, библиотека может выполнить ее и сделать то, что ей нужно, главным образом объединить полученное значение обратно со строчными значениями внутри массива.

Объединение наших новых знаний

Теперь, когда мы знаем, как работают литералы шаблона с тэгами, давайте глубже поймем `styled` API:

const Button = styled.button`  background: ${props => props.primary ? 'red' : 'white'};  color: black;`

styled.button является функцией тега. Если бы мы зарегистрировали аргументы этой функции, мы увидели бы следующее:

logArgs`  background: ${props => props.primary ? 'red' : 'white'};  color: black;`
// -> ["background: ", "; color: black;"]
// -> props => props.primary ? "red" : "white"

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

Итак, как работает другой шаблон?

Ах так. Вот почему ты здесь, не правда ли? Раньше я показал другой способ использования styled API, который я видел в последнее время:

const Button = styled('button')([],  'background: palevioletred',  'color: #fff')

Во-первых, поймите это styled.button и styled('button') обрабатываются так же. Они взаимозаменяемы.

Во-вторых, здесь нет тегированного действия литерала шаблона. Но, поскольку мы это знаем styled поддерживает их, мы знаем, как он ожидает своих аргументов. Это основной ключ?

Запомните два правила:

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

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

В шаблоне выше, которому я дам название «Шаблон пустого массива»аргументы:

// -> []
// -> 'background: palevioletred'
// -> 'color: #fff'

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

Мы имитировали поведение тегированных литералов шаблона, фактически не используя их.

Подведению

В конце дня оба шаблона дают одинаковое значение. Мне трудно понять, почему вы хотели использовать одно вместо другого. Я думаю, я видел ситуацию, когда, используя тегированные литералы шаблона, вы имели несколько интерполяций, и для читабельности кода вы могли выбрать Шаблон пустого массива вместо этого:

// as tagged template literal
const Button = styled.button`  background: ${ props => props.background };  color: ${ props => props.color };`
// as Empty Array Pattern
const Button = styed.button([], props => ({  background: props.background,  color: props.color}))

Я хотел бы услышать мнение от других, у которых есть опыт работы с этими шаблонами, а также услышать преимущества и недостатки каждого!

Это был перекрестный пост из моего собственного блога. ?

Передай привет в Twitter?

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

Ваш адрес email не будет опубликован.