Вызов комбинированного селектора повторного выбора из redux-saga

Я пытаюсь вызвать комбинированный селектор из redux-saga. По идее, у меня есть два выпадающих списка. Варианты в первом раскрывающемся списке будут отфильтровывать соответствующие значения во втором раскрывающемся списке, т.е. мой комбинированный селектор будет отфильтровывать некоторые нерелевантные значения, поэтому они не будут отображаться во втором раскрывающемся списке:

1) У меня есть два селектора firstSelector и secondSelector

// firstSelector returns {"Cat":["black","white"],"Dog":["grey"]}
const firstSelector= () =>
  createSelector(selectPage, substate => substate.firstDropDown);

// secondSelector returns ["black","grey"]
const secondSelector= () =>
  createSelector(selectPage, substate => substate.secondDropDown);

2) Я объединяю их в комбинированный селектор (который должен возвращать ["black", "grey"], т.е. "белый" отфильтрован)

const filterBySelection = (firstSelector, secondSelector) =>
  createSelector(
    [
      firstSelector, 
      secondSelector, 
    ],
    (first, second) => {
      const filteredValues = Object.keys(first).reduce(
        (r, k) => r.concat(first[k]),
        [],
      );
      return second.filter(val => filteredValues.indexOf(val) >= 0);
    },
  );

3) А как можно вызвать filterBySelection в redux-saga? Я пытался:

const filteredValues = yield select(
  filterBySelection,
  firstSelector,
  secondSelector,
);

А также

const filteredValues = yield select(
  filterBySelection(firstSelector, secondSelector)()
);

А также

const filteredValues = yield select(
  filterBySelection(firstSelector, secondSelector)
);

Но эти способы не работают.

Хотя могу назвать firstSelector или secondSelector, т.е. работает:

const firstData= yield select(firstSelector());

Кто-то может сказать, что я могу просто сделать следующее в redux-saga:

const first = yield select(firstSelector());
const second = yield select(secondSelector());
const filtered = Object.keys(first).reduce(
  (r, k) => r.concat(first[k]),
  [],
);
const secondFiltered = second.filter(
  val => first.indexOf(val) >= 0,
);

Но это будет not memoize, а идея - memoize.

Так можно ли использовать мемоизированный селектор в redux-saga?

С уважением


person user1665355    schedule 26.02.2019    source источник
comment
Я думаю, вы можете отбросить массив в createSelector, просто передайте subSelectors в качестве аргументов   -  person Kasia    schedule 26.02.2019


Ответы (2)


Кажется, вы пропустили вызов функции для возврата селектора. Итак, либо:

a)

const filterBySelection = (firstSelector, secondSelector) =>
  createSelector(
    [
       firstSelector(), // <- parentheses 
       secondSelector(), // <- parentheses 
     ], ... )

затем: const filteredValues = yield select( filterBySelection(firstSelector, secondSelector) );

б) правильно передать селекторы

const filteredValues = yield select(
  filterBySelection(firstSelector(), secondSelector())
);

в) определить firstSelector и secondSelector без функции (возможно, самый верный способ):

const firstSelector = 
  createSelector(selectPage, substate => substate.firstDropDown);

const secondSelector = 
  createSelector(selectPage, substate => substate.secondDropDown);

тогда

const filteredValues = yield select(
  filterBySelection(firstSelector, secondSelector)
);

Надеюсь, это поможет.

person Alex    schedule 26.02.2019
comment
Правильно ... Я пропустил вызов селекторов в комбинированном селекторе: P спасибо! - person user1665355; 26.02.2019

Я бы пошел с чем-то вроде этого

  createSelector(
    firstSelector, 
    secondSelector, 
    (first, second) => {
      const filteredValues = Object.keys(first).reduce(
        (r, k) => r.concat(first[k]),
        [],
      );
      return second.filter(val => filteredValues.indexOf(val) >= 0);
    },
  );```
person Kasia    schedule 26.02.2019
comment
Это и есть мой селектор. Это не вопрос / проблема. - person user1665355; 26.02.2019
comment
Я говорю, что вам следует отбросить массив - person Kasia; 27.02.2019
comment
а при удалении массива скобки () использовать не нужно. - person Kasia; 27.02.2019
comment
Спасибо! Я нашел это очень полезным. Я объединил отдельный селектор в основной и все заработало. Раньше отдельный селектор вызывал проблемы (фильтрация поискового запроса, а также отдельные радиофильтры). - person user.io; 22.07.2020