【问题标题】:Call combined reselect selector from redux-saga从 redux-saga 调用组合重选选择器
【发布时间】:2019-02-26 09:25:51
【问题描述】:

我正在尝试从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) 但是如何在redux-saga 中调用filterBySelection? 我试过了:

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 中使用 memoized 选择器?

最好的问候

【问题讨论】:

  • 我认为你可以在 createSelector 中删除数组,只需将 subSelector 作为参数传递
  • 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); }, );

标签: reactjs redux redux-saga reselect


【解决方案1】:

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

一)

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

希望对你有帮助。

【讨论】:

  • 正确...我错过了在组合选择器中调用选择器:P 谢谢!
【解决方案2】:

我会选择这样的东西

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

【讨论】:

  • 这正是我的选择器。这不是问题/问题。
  • 我是说,你应该删除数组
  • 和删除数组你不需要使用括号()
  • 谢谢!我发现这很有帮助。我将一个单独的选择器组合到主选择器中,一切正常。在单独的选择器引起问题之前(搜索词过滤以及单独的单选过滤器)。
猜你喜欢
  • 2017-09-14
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多