Mouarf
Mouarf

Reputation: 25

Why does my React Component not rerender after setState?

I'm fairly new to React & Redux, and I'm struggling with the React rerender mechanic.

I'm trying to write a simple ToDo app. Here is my ToDoList class:

class ToDoList extends Component<Props, State> {
    constructor(props: Props) {
        super(props);
        this.state = {
            todoList: this.sortTodos(props.todoList)
        };
    }

    render = () => {
        return (
            <List>
                {this.state.todoList.map((todoItem, index) => 
                    <ToDo key={index} info={todoItem} />
                )}
            </List>
        );
    }

    componentWillMount = () => {
        if (this.state.todoList.length === 0)
            this.props.loadToDoList();
    }

    componentWillReceiveProps = (nextProps: Props) => {
        this.setState({ todoList: this.sortTodos(nextProps.todoList) });
    }

    sortTodos = (todos: ToDoModel[]) => {
        return todos.sort((a, b) => a.completed === b.completed ? 0 : a.completed ? 1 : -1)
    }
}

When I check a todo, my ToDoModel is updated and componentWillReceiveProps is called.

I tried to count the number of completed todos and set this number in the state in the componentWillReceiveProps. It works, however, for some reason, my todo list isn't rerendered in the updated order, even with a this.forceUpdate() at the end of the function. (Actually, my todo isn't checked and re-ordered until I reload the screen.)

What am I missing?

Upvotes: 0

Views: 1590

Answers (2)

Mukesh Soni
Mukesh Soni

Reputation: 6668

Probably because of the key in Todo item. Try setting the key to the id of the item

<List>
  {this.state.todoList.map((todoItem, index) => 
    <ToDo key={todoItem.id} info={todoItem} />
  )}
</List>

Upvotes: 2

Stefan Maretić
Stefan Maretić

Reputation: 51

Inside map try to return the component:

{this.state.todoList.map((todoItem, index) => 
  return <ToDo key={index} info={todoItem} />;
)}

Upvotes: -1

Related Questions