从redux-saga调用组合的重新选择选择器

时间:2019-02-26 09:25:52

标签: reactjs redux redux-saga reselect

我正在尝试从redux-saga调用组合选择器。想法是我有两个下拉菜单。第一个下拉菜单中的选项将在第二个下拉菜单中过滤适当的值,即我的组合选择器将过滤掉一些不相关的值,因此它们不会在第二个下拉菜单中显示:

1)我有两个选择器,firstSelectorsecondSelector

// 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)
);

但是这些方法不起作用。

尽管如此,我可以打电话给firstSelectorsecondSelector,即可以正常工作:

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中使用记忆选择器吗?

最好的问候

2 个答案:

答案 0 :(得分:1)

您似乎错过了调用该函数以返回选择器的过程。因此,要么:

a)

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

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

b)正确通过选择器

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

c)定义不带功能的firstSelectorsecondSelector(也许是最正确的方式):

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

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

然后

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

希望有帮助。

答案 1 :(得分:0)

我会喜欢这样的东西

  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);
    },
  );```