在 Redux 的 Todo List 例子中真的需要 Reselect 吗?

Is Reselect really needed in the Todo List example in Redux?

我正在寻找提高我的 React 应用程序性能的方法。经过一番搜索后,我查看了 Reselect。但我不确定 example 是如何工作的。

在示例中,它指出每次更新组件时都会计算 todos,这会影响性能。所以引入了memoized selector的使用来克服它。

如果我把getVisibleTodos放在组件render函数里会有什么不同吗?我想做的是:

containers/VisibleTodoList.js

import React from 'react'
import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_ALL':
      return todos
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
  }
}

/*const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}*/

const mapStateToProps = (state) => {
  return {
    todos: state.todos,
    visibilityFilter: state.visibilityFilter
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

const VisibleTodoList = ({todos, visibilityFilter, ...props}) => {
  const visibleTodos = getVisibleTodos(todos, visibilityFilter);
  return (
    <TodoList todos={visibleTodos} {...props} />
  )
}

const ConnectedVisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(VisibleTodoList)

export default ConnectedVisibleTodoList

在这种情况下,除非 todosvisibilityFilter 发生变化,否则不会调用 getVisibleTodos。正确的?我的修改和选择器做的一样吗?我错过了什么吗?

不,getVisibleTodos 仍会被调用,并会在 VisibleTodoList 重新渲染时重新计算。

此外,由于 `VisibleTodoList` 是一个函数式组件,每次当它的父组件有更新时,它都会重新渲染。 所以不,您的代码和 Reselect 的行为不同。我猜你想要的是一个 class 组件,并添加 shouldComponentUpdate 来手动比较 todos 和 visibilityFilter ,这样你就可以避免不必要的计算。


VisibleTodoList被react-redux的connect包裹,react-redux已经为你提供了shouldComponentUpdate

但即使你使用shouldComponentUpdateconnect,它仍然不如Reselect优化。因为当您在 All、Active 或 Completed 选项卡之间切换时,将调用 getVisibleTodos 并且会有很多重复的重新计算。 (Reselect缓存了这些结果,所以没有重复重新计算)