Селекторы — это очень простой способ выбрать состояние из хранилища redux, которое содержит всю логику и данные приложения.
Если вы создаёте приложение с помощью React и Redux, от использования селекторов вы только выиграете.
Как выглядят селекторы?
Перед тем как мы разберемся, почему селекторы удобны и как их использовать, давайте посмотрим, как приложение выглядит без них. Я создал необходимый минимум — базовую установку Redux:
- У нас есть rootreducer, содержащий все данные о наших животных:
const initialState = { data: [ { name: "Milton", type: "cat", age: 4 }, { name: "Sammy", type: "dog", age: 2 }, { name: "Joseph", type: "turtle", age: 34 }, { name: "Simon", type: "dog", age: 8 } ] }; export default (state = initialState, action) => { switch (action.type) { default: { return { ...state }; } } };
- Наш rootreducer передается в хранилище, хранилище передается в <Provider>.
- В итоге PetsContainer.js подключается к хранилищу, выбирает животных, находит всех собак и выводит данные на экран.
OK, допустим, нам нужно выбрать данные всех собак из хранилища и отобразить их на экране. Как мы сделаем это? Наивный подход выглядит так:
Заметили что-нибудь странное? Фильтрация происходит внутри обратного вызова useSelector. Если мы сделаем так более одного раза, приложение сильно замедлится, не говоря уже о том, что это не самый красивый кусок кода. Если вы уже знакомы с Redux, вы знаете, что у нас есть редьюсеры для изменения и хранения состояния, действия для запуска триггеров изменения состояния. И третий кусочек пазла — селектор. Селекторы прекрасно дополняют картину, так как нам нужен эффективный способ получить данные из хранилища и отобразить их.
Заметьте: здесь мы используем React-хуки в сочетании с Redux.
Добавление библиотеки Reselect
Reselect — это простая библиотека селекторов для Redux и не только, вдохновленная геттерами в NuclearJS, подписками в re-frame и этим предложением от speedskater.
Вот почему стоит использовать селекторы с React и Redux приложениями:
- Селекторы могут просчитать производные данные, позволяя Redux сохранять минимальное возможное состояние.
- Селекторы эффективны — селектор не пересчитывается, пока один из его аргументов не изменится.
- Селекторы пригодны для компоновки — они могут использоваться внутри других селекторов.
Установка библиотеки Reselect
Установка библиотеки reselect очень проста — установите ее как любой пакет NPM:
yarn add reselect
Библиотека у нас есть, теперь давайте создадим новый файл под названием selectors.js — это файл, в котором хранится вся логика селекторов. Далее из библиотеки reselect импортируем метод createSelector:
import { createSelector } from "reselect";
Прекрасно! Теперь у нас есть доступ к методу createSelector.
Создание селектора
Селекторы очень просто понять. createSelector принимает столько аргументов, сколько вы захотите. Ключевой момент в том, что последний аргумент используется для фильтрации или выбора. Скажем, мы хотим выбрать всех собак. Вот что мы передаем селекторам:
- Передаем всех питомцев селектору в качестве первого аргумента — это зависимости.
- Последний аргумент — всегда обратный вызов, с аргументами в качестве зависимостей, переданных ранее.
Вот как выглядит код:
import { createSelector } from "reselect"; const selectAllPets = state => state.pets.data; export const selectAllDogs = createSelector( selectAllPets, allPets => allPets );
Теперь, если мы вернемся к PetsContainer, мы сможем импортировать селектор selectAllDogs и передать его redux-хуку useSelector:
Заметьте, что сейчас возвращаются данные всех питомцев. Это именно то, что мы делаем с помощью селектора. Чтобы получить данные всех собак, нам нужно применить логику фильтра внутри селектора:
Теперь у нас все собаки. Вместо того, чтобы фильтровать внутри компонента, мы просто отображаем всех собак. Это отличный способ снизить нагрузку на компоненты. Помните, компоненты React хороши для рендеринга разметки, все остальное стоит исполнять в другом месте, чтобы уменьшить количество спагетти-кода и разделить задачи.
Мы даже можем передавать селекторы в качестве аргументов другим селекторам. Как же нам выбрать всех собак и кошек в хранилище?
- Сначала мы получаем всех питомцев.
- Затем фильтруем всех собак и кошек.
- И объединяем их в один селектор, передавая селекторы в качестве аргументов.
Вот и все — приятные и простые компоненты React. Помните, результаты селектора хранятся в памяти и всегда возвращают тот же результат, пока результаты остаются неизменны. Это колоссально увеличивает производительность.
Если вы хотите поиграть с селекторами, вот код из песочницы и исходный код.
Специально для сайта ITWORLD.UZ. Новость взята с сайта NOP::Nuances of programming