Redux 重新选择-创建一个只用于获取部分状态的记忆选择器有意义吗?

Redux 重新选择-创建一个只用于获取部分状态的记忆选择器有意义吗?,redux,reselect,Redux,Reselect,我有一个普通选择器,用于获取部分状态: export const getAllPosts = state => { return state.posts; }; 如果使用“重新选择”包装选择器: import { createSelector } from 'reselect'; export const allPosts = createSelector( getAllPosts, (posts) => posts ); 这对提高绩效有意义吗?在我看来,包装器是不

我有一个普通选择器,用于获取部分状态:

export const getAllPosts = state => {
  return state.posts;
};
如果使用“重新选择”包装选择器:

import { createSelector } from 'reselect';

export const allPosts = createSelector(
  getAllPosts,
  (posts) => posts
);

这对提高绩效有意义吗?在我看来,包装器是不必要的。

不,这没有真正的好处

我发现我的第一级选择器只是简单的函数,任何更深层次的选择器都需要记忆:

// assume state is:  {first : {second {} } }

const selectFirst = state => state.first;

const selectSecond = createSelector(
    selectFirst,
    first => first.second
);

不,仅仅为了获取状态树的一部分而创建一个记忆选择器是没有意义的

原因是,
connect
将对从
mapStateToProps
传入的每个道具执行自己的浅层相等性检查。如果选择器返回的道具与其他道具一起通过了浅相等检查,则不会不必要地调用
render
。如果选择器只是返回状态树的一部分,而状态树的该部分没有被修改,那么浅层相等性检查就足够了

但是,如果选择器是根据其他选择器的结果计算的,则使用
createSelector
是一个不错的选择。首先,它为组合选择器提供了良好的语法。其次,如果组合选择器的计算成本可能很高,那么您将获得性能优势。第三,如果选择器要返回一个新的但相等的对象或数组,那么
connect
提供的浅层相等检查将是不够的。在这种情况下,
createSelector
提供的记忆将确保在输入未更改的情况下返回相同的对象或数组实例,然后浅层相等性检查将足以避免代价高昂的重新渲染

因此,仅公开状态树的一部分
createSelector
不会添加任何内容


对于几乎所有从状态树的多个部分计算的选择器,
createSelector
开始添加值。它添加的值量根据选择器的不同而有所不同,从更易于读取到确保您不会不必要地重新呈现组件树。

在您的情况下,它没有意义,因为您只是从存储返回了相同的引用,该引用始终等于其自身(或其以前的状态)除非你修改它

如果设想不同的场景,例如,将实体存储在对象中而不是存储在存储中的数组中,但希望将数组返回到组件,则需要派生数据:

export const selectAllPosts = createSelector(
  getAllPostsFromStore, // returns { 1: {...}, 2: {...} }
  (allPosts) => Object.keys(allPosts).map(key => allPosts[key])
);
现在,选择器变成了性能提升,因为它只在存储区中的某些内容发生更改时计算派生数据


因此,我的经验法则是:如果不派生数据,就不需要记忆它。

为什么要记忆selectSecond?我看不到明显的性能改进。你能再解释一下吗?这个例子很简单。但是,假设
selectSecond()
的输出选择器正在执行一些昂贵的工作(可能是对数组进行排序/过滤),我们只想在数组发生更改时执行此操作。使用
createSelector()
并记忆输入将确保输出选择器仅在输入发生更改时运行。这个问题很好-我在任何地方都找不到解决方法。