在 Redux 应用程序中,当我们需要根据 state 中的数据计算出一个派生的数据时,我们通常使用 selector 函数。这些函数的作用是接收 state,然后返回一个新的派生数据。但是,当我们使用多个 selector 函数来计算派生数据时,可能会出现重复计算的问题,这会导致性能下降。为了解决这个问题,我们可以使用 Reselect 库。
Reselect 简介
Reselect 是一个用于创建可记忆的 selector 函数的库。它的主要作用是优化重复计算,并且可以缓存计算结果,以便在相同的输入情况下直接返回缓存的结果。这样,我们就可以避免不必要的计算,提高应用程序的性能。
Reselect 的核心概念是 memoization(记忆化)。当我们调用 selector 函数时,Reselect 会检查输入参数是否与上一次调用时相同。如果是,则直接返回缓存的结果,否则,重新计算并缓存结果。
使用 Reselect
下面是一个简单的示例,演示如何使用 Reselect。
首先,我们定义两个 selector 函数:
const getTodos = state => state.todos; const getVisibilityFilter = state => state.visibilityFilter;
这两个函数分别从 state 中获取 todos 和 visibilityFilter。
然后,我们使用 Reselect 创建一个新的 selector 函数:
import { createSelector } from 'reselect'; const getVisibleTodos = createSelector( [getTodos, getVisibilityFilter], (todos, visibilityFilter) => { switch (visibilityFilter) { case 'SHOW_ALL': return todos; case 'SHOW_COMPLETED': return todos.filter(todo => todo.completed); case 'SHOW_ACTIVE': return todos.filter(todo => !todo.completed); default: throw new Error('Unknown filter: ' + visibilityFilter); } } );
这个函数接收两个参数:一个数组和一个函数。数组中的元素是我们要从 state 中获取的数据,这些数据将作为参数传递给函数。函数的作用是将输入数据转换为一个新的派生数据。在这个示例中,我们根据 visibilityFilter 过滤 todos。
现在,我们可以在组件中使用这个新的 selector 函数:
import React from 'react'; import { connect } from 'react-redux'; import { getVisibleTodos } from './selectors'; const TodoList = ({ todos }) => ( <ul> {todos.map(todo => ( <li key={todo.id}>{todo.text}</li> ))} </ul> ); const mapStateToProps = state => ({ todos: getVisibleTodos(state) }); export default connect(mapStateToProps)(TodoList);
这个组件从 state 中获取可见的 todos,并将它们渲染成一个列表。
总结
Reselect 是一个非常有用的库,可以帮助我们优化 Redux 应用程序的性能。使用 Reselect,我们可以避免重复计算,提高应用程序的响应速度。如果你使用 Redux 开发应用程序,那么我强烈建议你学习并使用 Reselect。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c5e2d9add4f0e0ff066f3b