Объяснение аргументов функции селектора Redux/reselect?
Я работаю над кодовой базой, написанной на Typescript, которая использует много неизменяемых повторных выборов. Я еще не работал с повторным выбором, и я столкнулся с примером, который я не понимаю:
export const panelsSelector: (
order: Order,
events: List<List<Event>>,
adminRole: boolean,
packageEvents: List<List<PackageEvent>>,
) => List<PanelProps> = createImmutableEqualSelector(
(order: Order) => order,
(order: Order, events: List<List<Event>>) => events,
(order: Order, events: List<List<Event>>, adminRole: boolean) => adminRole,
(order: Order, events: List<List<Event>>, adminRole: boolean, packageEvents: List<List<PackageEvent>>) => packageEvents,
(order, events, adminRole, packageEvents) => List<PanelProps>([
{
content: <Events packageEvents={packageEvents}
events={events}
/>
},
{
content: <MyComponent packages={order.get('packages')}
adminRole={adminRole}
packagesCount={order.get('noOfPackages')}/>
},
)
Если я правильно читаю
panelsSelector
присваивается, я думаю, анонимный тип, который является функцией. В этом случае я думаю
createImmutableEqualSelector
возвращает функцию, которая возвращает
List<PanelProps>
. Чтобы упростить что-то вроде этого:
const panelsSelector:(arg) => List<PanelProps> = createImmutableEqualSelector((arg) => List<PanelProps>)
Чего я не понимаю в этом примере, так это того, почему селекторы должны иметь аргумент, добавленный из его предшественника в список аргументов?
(order: Order) => order,
(order: Order, events: List<List<Event>>) => events,
(order: Order, events: List<List<Event>>, adminRole: boolean) => adminRole,
(order: Order, events: List<List<Event>>, adminRole: boolean, packageEvents: List<List<PackageEvent>>) => packageEvents
Если я удалю аргумент из предшественника, например, для второго селектора:
(events: List<List<Event>>) => events
Я получаю ошибку машинописного текста:
Типы параметров «состояние» и «порядок» несовместимы.
Итак, почему эти селекторы должны быть написаны именно так? До сих пор я видел только простые примеры, подобные этому, где мы получаем данные из состояния:
const selectShopItems = state => state.shop.items
Но я не понимаю предыдущий пример. Если порядок не является состоянием, то откуда берутся эти данные?
1 ответ
Когда вы вызываете селектор Reselect, например
selectThing(state, 2, 3, 4)
, Reselect затем вызовет каждый из селекторов ввода с каждым из тех же входов:
const input1Result = inputSelector1(state, 2, 3, 4);
const input2Result = inputSelector2(state, 2, 3, 4);
const input3Result = inputSelector3(state, 2, 3, 4);
// etc
Затем Reselect передает каждый из этих результатов в окончательный «селектор вывода»:
const finalResult = outputFunction(input1Result, input2Result, input3Result);
Таким образом, все входные функции будут вызываться с одними и теми же аргументами.
Очень часто используется один или два селектора ввода, которые извлекают данные из Redux.
state
, но также и для извлечения некоторых дополнительных параметров:
const selectItemId = (state, itemId) => itemId;
В этом случае тот, кто писал, решил не указывать явно все четыре параметра для всех селекторов ввода. Это нормально, потому что JS позволяет вам вызывать функцию с большим количеством параметров, чем ей на самом деле нужно — просто все они должны быть правильно выстроены (т. е. все они должны ожидать
events
быть вторым аргументом).
У меня есть пара замечаний по поводу этого конкретного селектора:
Во-первых, нет необходимости явно указывать тип
panelsSelector
. TS будет знать, что это функция, которая принимает эти аргументы и возвращает этот результат.
Во-вторых, наличие селектора, возвращающего JSX, кажется... немного схематичным? Это сработает, но лично я бы постарался этого избежать. Я хотел бы вернуть только структуру данных и сохранить часть JSX в фактическом компоненте.
Обратите внимание, что в последней версии Reselect (4.1.x) также значительно улучшены типы TS.
И, наконец, мы рекомендуем вообще не использовать сегодня Immutable.js с Redux , особенно с учетом того, что наш официальный пакет Redux Toolkit построен на использовании Immer для неизменяемых обновлений.
Вы также можете прочитать страницу документации Redux о получении данных с помощью селекторов .