'React Component doesn't rerender after sorting array in store

I'm learning React and Redux and followed the tutorial on the Redux site. I'm trying to add a feature that lets user sort the todos by name, date, etc. The problem is the todo list doesn't rerender itself when I sort the array of todos. The state.sortBy is dispatched by different component and it's working. I can clearly see that the array is sorted by logging store.getState() to console. And the component is of course subscribed to the store.

The array changes. When I sort by "date" it's sorted by date. When I sort by "name" it's sorted by name. But the todo list component ignores it and doesn't rerender.

Here's the code for the todo list container component:

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

const sortTodos = (todos, sortBy) => {
  switch (sortBy) {
    case "date":
      return todos.sort((a, b) => Date.parse(b.date) - Date.parse(a.date))
    case "name":
      return todos.sort((a, b) => {
        if (a.name < b.name)
          return -1
        if (a.name > b.name)
          return 1
        return 0
      })
    default:
      return todos
  }
}

const mapStateToProps = (state) => ({
  todos: sortTodos(state.todos, state.sortBy)
})

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

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

And here is the presentational component:

import React from 'react'
import Todo from './Todo'

const TodoList = ({ todos, onTodoClick }) =>
  <ul>
    {todos.map((todo) =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>

export default TodoList

I've tried couple things and I got it working, but I think it's not the correct way to do this. When I appended .slice(0, -1) to the return statement of sortTodos function, the component rerendered.

const sortTodos = (todos, sortBy) => {
  switch (sortBy) {
    case "date":
      return todos.sort((a, b) => Date.parse(b.date) - Date.parse(a.date)).slice(0, -1)
.
.
.

Thanks for help



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source