Как правильно использовать функцию createSelector (библиотека reselect) с хуком useSelector в приложении React?
Первая закомментированная строка в компоненте App (где я деструктурирую объект) работает хорошо: я получаю билеты с сервера и отображаю их в компоненте. Но мне необходимо добавить сайд-эффекты в массив билетов (сортировка, фильтрация), поэтому я решил использовать селектор. Однако, при использовании такой записи const tickets = useSelector(sorterSelector) , селектор возвращает undefined (ошибка TypeError: Cannot read property ‘map’ of undefined ). При данной записи и логике, которую я описал в sorterSelector , я даже не вижу, что функция fetchData в useEffect запускается. Как решить эту проблему?
CSS селекторы: комбинаторы

Правила CSS соответствуют элементам с селекторами . Есть несколько способов сделать это, и вы, вероятно, знакомы с большинством из них. Тип элемента, имя класса, ID и селекторы атрибутов хорошо поддерживаются и широко используются.
Спецификации Селекторов Уровня 3 и Уровня 4 представили несколько новых селекторов. В некоторых случаях это новые варианты существующих типов. В других случаях они являются новыми функциями языка.
В этой главе мы рассмотрим текущий ландшафт браузера для селекторов CSS с акцентом на новые селекторы. Это включает в себя новые селекторы атрибутов и комбинаторы, а также ряд новых псевдоклассов. В разделе « Выбор селекторов мудро» мы рассмотрим концепцию специфики.
Эта глава не является исчерпывающим обзором всех селекторов – это может быть книга сама по себе. Вместо этого мы сосредоточимся на селекторах с хорошей поддержкой браузера, которые, вероятно, будут полезны в вашей текущей работе. Некоторый материал может быть старой шляпой, но это включено для контекста.
Совет: охват браузерами селекторов
Всесторонний взгляд на текущее состояние поддержки селекторов в браузере можно найти в CSS4-Selectors.
Комбинаторы
Комбинаторы – это последовательности символов, которые выражают отношения между селекторами по обе стороны от него. Использование комбинатора создает так называемый сложный селектор. Сложные селекторы , в некоторых случаях, могут быть наиболее кратким способом определения стилей.
Вы должны быть знакомы с большинством этих комбинаторов:
- комбинатор потомка или символ пробела
- детский комбинатор, или >
- комбинатор соседнего брата или +
- общий братский комбинатор, или ~
Давайте проиллюстрируем каждый из этих комбинаторов. Мы будем использовать их для добавления стилей в форму HTML, показанную ниже.

Эта форма была создана с использованием следующего фрагмента HTML:
form method="GET" action="/processor"> h1>Buy Tickets to the Web Developer Galah1> p>Tickets are $10 each. Dinner packages are an extra $5. All fields are required.p> fieldset> legend>Tickets and Add-onslegend> p> label for="quantity">Number of Ticketslabel> span class="help">Limit 8span> input type="number" value="1" name="quantity" id="quantity" step="1" min="1" max="8"> p> p> label for="quantity">Dinner Packageslabel> span class="help">Serves 2span> input type="number" value="1" name="quantity" id="quantity" step="1" min="1" max="8"> p> fieldset> fieldset> legend>Paymentlegend> p> label for="ccn">Credit card numberlabel> span class="help">No spaces or dashes, please.span> input type="text" id="ccn" name="ccn" placeholder="372000000000008" maxlength="16" size="16"> p> p> label for="expiration">Expiration datelabel> span class="help">abbr title="Two-digit month">MMabbr>/abbr title="Four-digit Year">MMabbr>YYYYspan> input type="text" id="expiration" name="expiration" placeholder="01/2018" maxlength="7" size="7"> p> fieldset> fieldset> legend>Billing Addresslegend> p> label for="name">Namelabel> input type="text" id="name" name="name" placeholder="ex: John Q. Public" size="40"> p> p> label for="street_address">Street Addresslabel> input type="text" id="name" name="name" placeholder="ex: 12345 Main Street, Apt 23" size="40"> p> p> label for="city">Citylabel> input type="text" id="city" name="city" placeholder="ex: Anytown"> p> p> label for="state">Statelabel> input type="text" id="state" name="state" placeholder="CA" maxlength="2" pattern="[A-W]" size="2"> p> p> label for="zip">ZIPlabel> input type="text" id="zip" name="zip" placeholder="12345" maxlength="5" pattern="0-9" size="5"> p> fieldset> button type="submit">Buy Tickets!button> form>
Потомок Комбинатор
Вы, наверное, довольно хорошо знакомы с потомком комбинатора. Это было вокруг с первых дней CSS (хотя это было без имени типа до CSS2.1). Это широко используется и широко поддерживается.
Комбинатор-потомок – это просто пробельный символ. Он отделяет родительский селектор от его потомка, следуя шаблону AB , где B – это элемент, содержащийся в A. Давайте добавим немного CSS в нашу разметку сверху и посмотрим, как это работает:
form h1 color: #009; >
Мы только что изменили цвет заголовка нашей формы, результат которого можно увидеть ниже.

Давайте добавим еще немного CSS, на этот раз, чтобы увеличить размер нашего сообщения о ценах («Билеты по 10 долларов США каждый»):
form p font-size: 22px; >
Однако есть проблема с этим селектором, как вы можете видеть ниже. Мы фактически увеличили размер текста во всех абзацах нашей формы, а это не то, что нам нужно. Как мы можем это исправить? Давайте попробуем детский комбинатор.

Детский комбинатор
В отличие от комбинатора-потомка дочерний комбинатор (>) выбирает только непосредственные дочерние элементы элемента. Он следует шаблону A> B , сопоставляя любой элемент B, где A является непосредственным предком.
Если бы элементы были людьми, по аналогии, дочерний комбинатор соответствовал бы дочернему элементу материнского элемента. Но потомок комбинатор также будет соответствовать ее внукам и правнукам. Давайте изменим наш предыдущий селектор, чтобы использовать дочерний комбинатор:
form > p font-size: 22px; >
Теперь это касается только прямых потомков article

Смежный брат и сестра комбинатор
С помощью соседнего братского комбинатора ( + Это следует схеме A + B. Стили будут применены к элементам B, которым непосредственно предшествуют элементы A.
Давайте вернемся к нашему примеру. Обратите внимание, что наши метки и входы расположены рядом друг с другом. Это означает, что мы можем использовать соседний братский комбинатор, чтобы они располагались на отдельных строках:
label + input display: block; clear: both; >
Вы можете увидеть результаты ниже.

Давайте посмотрим на другой пример, который объединяет универсальный селектор (*) с селектором типа:
* + fieldset margin: 5em 0; >
В этом примере поле 5em fieldset Поскольку мы используем универсальный селектор, не нужно беспокоиться о том, является ли предыдущий элемент другим fieldset p

Примечание: больше вариантов использования соседнего селектора
Хейдон Пикеринг (Heydon Pickering) исследует более умные способы использования соседнего селектора брата в своей статье «Аксиоматический CSS и лоботомизированные совы».
Что, если мы хотим стилизовать элемент родного брата, который не соседствует с другим, как в нашем поле Number of Tickets ? В этом случае мы можем использовать общий братский комбинатор.
Генеральный брат и сестра комбинатор
С помощью общего братского комбинатора « тильда» мы можем выбирать элементы, которые имеют одного и того же родителя, не считая их смежными. Учитывая шаблон A ~ B , этот селектор сопоставляет все элементы B, которым предшествует элемент A , независимо от того, являются ли они смежными.
Давайте снова посмотрим на поле « Количество билетов» . Его разметка выглядит так:
p> label for="quantity">Number of Ticketslabel> span class="help">Limit 8span> input type="number" value="1" name="quantity" id="quantity" step="1" min="1" max="8"> p>
Наш input label span Поскольку элемент span input label Давайте изменим наш соседний братский комбинатор на общий братский комбинатор:
label ~ input display: block; >
Теперь все наши input label

Использование обычного братского комбинатора наиболее удобно, когда вам не хватает полного контроля над разметкой. В противном случае вам лучше отрегулировать разметку, чтобы добавить имя класса. Имейте в виду, что общий братский комбинатор может создавать некоторые непреднамеренные побочные эффекты в большой базе кода, поэтому используйте его с осторожностью.
Что такое ticket и как им воспользоваться
В каждом проекте есть базовый параметр Ticket, который можно использовать в рассылках. Он отвечает за секретные хеши клиента и доступен во всех письмах и смс.
Ticket нужен для поиска клиента в системе и его авторизации на сайте из писем или смс без ввода паролей.
Существует 2 способа, благодаря которым мы можем найти и авторизовать клиента на сайте:
- Через мобильный телефон;
- Через e-mail адрес.
Рассмотрим каждый из них подробнее.
- EmailAuthenticationHexTicket — Предназначен для использования в ссылках, в которых мы можем авторизовать клиента по e-mail. Этот параметр ограничен по времени и действует в течение 30-ти минут от указанной в нем даты отправки письма.
- EmailAuthenticationTicket — Этот параметр используют для ссылок, которые ведут на промо-сайты и т.д. Время действия этого параметра не ограничено.
- EmailConfirmationLinkTicket — Параметр используется для подтверждения e-mail адреса и подписки на рассылки. Например, при подтверждении подписки.
- MobilePhoneAuthenticationHexTicket — Тут мы уже сможем авторизовать клиента по номеру телефона. Параметр также действует в течение 30-ти минут от указанной в нем даты.
- PermanentAuthenticationTicket — В этом параметре мы не ограничиваем время действия авторизации. В основном, используется для восстановления пароля пользователя.
Все эти тикеты работают по одному принципу. Когда пользователь пытается войти в систему, сервер сравнивает данные, полученные от пользователя, со своими. Если они совпадают, то пользователь авторизуется без логина и пароля на сайте. Если нет — то пользователю сообщается, что он ввел неверные данные в системе. Также ему нужно заново авторизоваться на сайте.

Проверить работу тикета можно через раздел «Интеграции»:
Чтобы вставить ticket в рассылку, используйте базовый параметр ticket с нужным значением из списка:
Псевдоклассы СSS :not() и :target
Сегодня мы рассмотрим менее распространенные псевдоклассы CSS , которые поддерживаются в современных браузерах: child-indexed и typed child-indexed , а также псевдоклассы для элементов ввода input . Псевдоклассы child-indexed и typed child-indexed позволяют выделять элементы по их расположению в дереве документа. Псевдоклассы input определяют поля формы на основе их значений и состояний.
Обновлено: 2022-01-16 17:27:47 Валентин Сейидов автор материала
Подсветка фрагментов страницы псевдоклассом :target
В этом случае идентификатор фрагмента является частью URL , который следует после хеша # ( например, #top или #footnote1 ). Такое часто используется для организации навигации по странице при помощи так называемой « jump-link ». С помощью псевдокласса :target можно подсветить фрагмент документа:
Comments on this post
. . .
После нескольких штрихов и работы с CSS получается результат, который приведен ниже:

Каждый comment в коде обозначен идентификатором, который позволяет ссылаться на конкретный фрагмент. Например, . Всё что остаётся – это стилизовать комментарий, используя псевдокласс CSS child :target :
.comment:target
Когда идентификатор фрагмента в URL совпадает с комментарием ( например , http://example.com/post/#comment-1146937891 ), он будет подсвечен жёлтым цветом, как показано ниже:

Псевдокласс CSS :target позволяет создавать комбинации, что открывает пространство для манёвров и позволяет не использовать JavaScript . Стилизуем наш пример с помощью CSS3 . Для начала посмотрите на HTML-код :
Здесь всё просто: три вкладки и контент с привязкой. Добавим CSS :
[id^=tab] < position: absolute; >[id^=tab]:first-child < z-index: 1; >[id^=tab]:target
Здесь и начинается волшебство. Сначала мы задаём вкладкам абсолютное позиционирование. Затем располагаем первую вкладку поверх контента при помощи свойства z-index: 1 . Это важно, если при первом посещении пользователи должны видеть именно эту вкладку. Добавляем свойство z-index 1 к нашей вкладке target . Это гарантирует, что выделенный слой всегда будет расположен поверх остального контента. Результат представлен ниже:

Улучшаем доступность
В более доступной версии ( в том числе и псевдоклассах CSS ссылок ) можно использовать JavaScript для переключения атрибутов hidden и aria-hidden=true .
Клик по вкладке обновляет URL с использованием нового идентификатора фрагмента, после чего приводится в действие состояние :target .
Отрицание селекторов при помощи :not()
Одним из самых многофункциональных считается псевдокласс :not() . Он возвращает все элементы, за исключением тех, которые совпадают с аргументом селектора. Например, p:not(.message) выделяет все элементы p без класса message .
Псевдокласс :not() принимает один аргумент, как и большинство функций в других языках программирования. Любой аргумент, заданный в :not() , должен быть простым селектором, названием класса или ID , другим псевдоклассом. Псевдоклассы не работают так, как составные селекторы типа label.checkbox или сложные селекторы типа p img .
Посмотрите на пример формы, в которой используется текстовые элементы ввода и radio buttons :
В HTML label , ассоциированные с элементами типа radio , имеют класс .label-radio . Можно использовать псевдокласс CSS нажатия :not() для выделения элементов, не имеющих класса label-radio , как это показано на картинке ниже:
label:not(.label-radio)

Рассмотрим более сложный пример. Используем стилизацию текстовых полей. Сюда входят элементы ввода number , email и text , а также password и url . Кроме этого мы исключим элементы radio , checkbox и range . Вам наверняка захочется воспользоваться следующим списком селектора:
([type=radio]), input:not([type=checkbox]), input:not([type=range])
К сожалению, это не поможет, так как каждый новый селектор переписывает предыдущий. Это всё равно, что писать:
input:not([type=radio]) < . >input:not([type=checkbox]) < . >input:not([type=range])
Вместо этого, нужно связать псевдоклассы :not() в цепочку, чтобы они отфильтровывали все элементы input :
input:not([type=radio]):not([type=checkbox]):not([type=range])
Приведённая цепочка селекторов также соответствует элементам [type=image], [type=reset], [type=color] и [type=submit]
Использование псевдоклассов и псевдоэлементов CSS без простого селектора эквивалентно его использованию с универсальным селектором. Другими словами, :not([type=radio]) – то же, что и *:not([type=radio]) . В данном случае нашему критерию отвечает любой элемент без атрибута type и значения radio , включая html и body . Чтобы предотвратить это, используйте :not() с названием класса, ID или селектор атрибутов в качестве селектора.
В CSS Class-селекторах Level 4 изменен принцип работы :not() , так что, теперь он принимает в качестве аргумента не только простые селекторы, но и списки. Вместо того чтобы связывать классы, как это делалось раньше, можно указывать аргументы через запятую:
input:not([type=radio], [type=checkbox], [type=range])
К сожалению, пока далеко не все браузеры поддерживают этот вариант, поэтому мы рекомендуем и дальше использовать цепочки.
Валентин Сейидов автор-переводчик статьи « CSS Pseudo-classes: :not() and :target »