Created with 💙 by Anh
View online here.
- Takehome message:
- eventHandlers take care of initiating the function via user interaction, there is no need to use useEffect method
- We usually return the new array/object with updated state and/or styling of items instead of returning one single item/styling condition in the array/object
- Styling does not work after we check the todo checkbox because
props.item.completedis updated byhandleChange()method within the scope ofaddtodochild component only. The updated state byhandleChange()method is not passed down to grandchild compopenttodoitem.
The item object has 3 keys: id, text, completed. Completed key is set false by default which is its initital state within addtodo child component.
After clicking on the checkbox of the first item idexed 0 (see the image), its key completed turned true in the new array returned by handleChange() method within addtodo. This new state is not passed down to <TodoItem /> in other words, the updated properties of todoList array is not mapped down to props BECAUSE todoList state is not updated by setTodoList. WHY?
Previously, setTodoList takes a function as an argument:
const handleChange = (id) => {
setTodoList(() => { todosData.map(item => {
if (item.id === id) {
item.completed = !item.completed
}
return item;
})
return todoList;
})
};
In order for setTodoList to work, the argument has to be an object which is the todoList array. You do not need to return todoList when you already uses map method
setTodoList(todoList.map(item => {
if (item.id === id) {
item.completed = !item.completed
}
return item;
})
)};
setTodoList() now returns updated state for each items (here is 5 items). But the styling still does not work. As in the instruction of Scrimba (Reactjs), the styling must be done in the child component, not the parent. However, since the style depends on the state of todoList object, my solution is to create another key completeStyle which will return styling for the whole list too by using the item.completed condition.


