在 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
在这种情况下,除非 todos
或 visibilityFilter
发生变化,否则不会调用 getVisibleTodos
。正确的?我的修改和选择器做的一样吗?我错过了什么吗?
不,getVisibleTodos
仍会被调用,并会在 VisibleTodoList
重新渲染时重新计算。
此外,由于 `VisibleTodoList` 是一个函数式组件,每次当它的父组件有更新时,它都会重新渲染。
所以不,您的代码和 Reselect 的行为不同。我猜你想要的是一个 class 组件,并添加 shouldComponentUpdate 来手动比较 todos 和 visibilityFilter ,这样你就可以避免不必要的计算。
VisibleTodoList
被react-redux的connect
包裹,react-redux已经为你提供了shouldComponentUpdate
但即使你使用shouldComponentUpdate
或connect
,它仍然不如Reselect优化。因为当您在 All、Active 或 Completed 选项卡之间切换时,将调用 getVisibleTodos
并且会有很多重复的重新计算。 (Reselect缓存了这些结果,所以没有重复重新计算)
我正在寻找提高我的 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
在这种情况下,除非 todos
或 visibilityFilter
发生变化,否则不会调用 getVisibleTodos
。正确的?我的修改和选择器做的一样吗?我错过了什么吗?
不,getVisibleTodos
仍会被调用,并会在 VisibleTodoList
重新渲染时重新计算。
VisibleTodoList
被react-redux的connect
包裹,react-redux已经为你提供了shouldComponentUpdate
但即使你使用shouldComponentUpdate
或connect
,它仍然不如Reselect优化。因为当您在 All、Active 或 Completed 选项卡之间切换时,将调用 getVisibleTodos
并且会有很多重复的重新计算。 (Reselect缓存了这些结果,所以没有重复重新计算)