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
sort
does inplace array sorting (modifies the array itself). You need to make a copy before sorting. For example
todos.slice(0).sort((a, b) => Date.parse(b.date) - Date.parse(a.date))
or
[...todos].sort((a, b) => Date.parse(b.date) - Date.parse(a.date))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With