1
votes

I am looking ways to improve performance of my React application. After some searching, I look into Reselect. But I am not sure how the example works.

In the example, it states that todos is calculated every time the component is updated which hurts performance. So it introduces the use of memoized selector to overcome it.

Will there be difference if I put getVisibleTodos in the component render function? What am I thinking to do is like:

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

In this case, getVisibleTodos won't be called unless todos or visibilityFilter change. Right? Does my modification do the same as the selectors do? Am I missing something?

1
Don't optimise something you cannot measure. - zerkms
@zerkms I think that's why he is asking for help. - Rafael Berro
@RafaelBerro I don't think so, they ask for a general advice. - zerkms

1 Answers

2
votes

No, getVisibleTodos will still be called and will re-calculate when VisibleTodoList re-renders.

Besides, since `VisibleTodoList` is a functional component, it will be re-rendered every single time when its parent component has an update. So no, your code and Reselect behave differently. I guess what you want is a class component, and add `shouldComponentUpdate` to compare `todos` and `visibilityFilter` manually, then you can avoid unnecessary calculations.


VisibleTodoList is wrapped by connect of react-redux, and react-redux has already provided a shouldComponentUpdate for you.

But even if you use shouldComponentUpdate or connect, it's still not as optimized as Reselect. Because when you switch between All, Active or Completed tabs, getVisibleTodos will be called and there will be a lot of duplicated re-calculations. (Reselect caches these results, so there is no duplicated re-calculation)