开发者问题收集

传递给“reselect”的函数是否可以包含其他选择器和函数,同时仍保留 createSelector 记忆化的好处?

2019-02-03
564

我理解“reselect”背后的记忆概念,并使用它来组成我的 Redux 选择器,但我不完全确定 createSelector 如何“知道”组件选择器的数据何时发生变化,以及在这些“子选择器”中包含其他函数调用是否会干扰 createSelector 的记忆。

问题在于,在“子选择器”中,即我传递给 createSelector 的函数,我需要执行一些基本检查,以确保 JSON 数据树的某些部分不是 unedefined (我为此使用了 ramda 库),并且还要按名称 选择 JSON 数据树的一部分。也就是说,在“子选择器” getParksData 中,我正在调用其他模块中的 existsAtnameToBlockData 。(我知道在下面的例子中,我仅从一个“子选择器”中进行组合;我稍后会添加其他子选择器)。

当我调用其他函数时,我是否仍能保持 createSelector 的所有记忆优势?我是否需要以某种方式记忆这些函数?谢谢提供任何信息!

import { createSelector } from 'reselect';

import existsAt from '../../../utils/objectExistsAtPath';

import {
  nameToBlockData,
  HOME_DATA_FEATURE_PARKS,
} from '../../../api/json-name-to-block-data';

const R_BASE = 'home.data.blocks';


// eslint-disable-next-line
const getParksData = (state, position) => (existsAt(R_BASE,  state) ? nameToBlockData(state.home.data.blocks, HOME_DATA_FEATURE_PARKS).sub_blocks.find(element => element.position === position) : {});

export default createSelector(
  [getParksData],
  (parksData) => (parksData),
);
1个回答

createSelector 将计算所有输入选择器。如果它们是使用 createSelector 创建的,它们也将被记忆。

记忆仅检查输入参数,因此只要您的状态(或子状态)没有改变,您仍将获得记忆的好处。

请注意,我调用了 barSelector 两次,但 getFoo 仅执行了一次

const {
  createSelector
} = Reselect

const getFoo = (thing) => {
  console.log('getFoo')
  return thing.foo
}

const state = {
  foo: {
    bar: 1
  },
}

const fooSelector = state => getFoo(state)

const barSelector = createSelector(
  fooSelector,
  foo => foo.bar
)


console.log(barSelector(state))
console.log(barSelector(state))
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>
thedude
2019-02-03