我们可以为每个选择器甚至是最简单的 getter使用带有 redux 的 Reselect memoization 吗?

问题描述

我是 Redux 的新手,我一直在阅读有关它的相当不错的东西,包括记忆技术(尤其是重新选择)。 不过我有一个问题,我很难找到正确的答案。 如果我们为每个选择器添加记忆(假设我们有很多),即使是简单的 getter,它是否会导致性能问题(可能是因为引擎盖下的记忆数据?)? 复杂选择器的记忆显然是有益的,因为它可以防止在不需要时重新计算。 但我发现简单选择器的记忆化也有好处,可以避免无用的重新渲染。

事实上,我使用 useSelector 钩子和文档状态:

一个动作被分派时,useSelector() 会对前一个选择器结果值和当前结果值进行引用比较。如果它们不同,组件将被迫重新渲染。如果它们相同,则组件不会重新渲染。

因此,即使选择器返回相同的原始值(例如 int),如果我没有错,useSelector 应该始终使组件重新呈现(即使选择器始终返回相同的值)。

如果我说的是真的,记住即使是简单的 getter 对此也很有用,但过度使用它会导致其他性能问题吗?

感谢您的帮助

解决方法

编写记忆选择器函数很有用,但是许多人试图记住太多不应该记忆的选择器

如果选择器函数只是简单地查找并从状态中返回现有数据,则无需记住它——它可能只是一个简单的函数。例如:

const selectTodoById = (state,id) => state.todos.entities[id];

其次,您可能也不应该为每个单独的状态字段创建单独的选择器。找到合理的粒度级别。

记忆化选择器仅在选择器返回一些派生数据时才有用。一个很好的例子是过滤一个数组:

const selectCompletedTodos = createSelector(
  state => state.todos,state => state.filters.completed,(todos,completed) => todos.filter(t => t.completed === completed)
);

这样,只有在输入值发生变化时才会重新计算派生数据。

作为旁注,我实际上计划编写一个新的 Redux 核心文档页面,其中包含有关何时以及如何编写记忆选择器的指导和使用信息。在此之前,您可以阅读我的帖子 Using Reselect Selectors for Encapsulation and Performance ,其中已经涵盖了很多内容。