1

I tried to use handleChange method to change the completed boolean who is responsible for checking the box but it does not change .. I can't find where it's missed up

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            todos: todosData
        }
        this.handleChange = this.handleChange.bind(this)
    }
    
    handleChange(id) {
        this.setState((prevState) => {
            const updatedTodos = prevState.todos.map(todo => {
                if (todo.id === id) {
                    todo.completed = !todo.completed
                }
                return todo
            })
            return {
                todos: updatedTodos
            }
        })
        
    }
    
    render() {
        const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange}/>)
        
        return (
            <div className="todo-list">
                {todoItems}
            </div>
        )    
    }
}

export default App

and this is my ToDoItem component

function TodoItem(props) {
    return (
        <div className="todo-item">
            <input 
                type="checkbox" 
                checked={props.item.completed} 
                onChange={() => props.handleChange(props.item.id)}
            />
            <p>{props.item.text}</p>
        </div>
    )
}

export default TodoItem

1 Answer 1

1

Issue

You are mutating your state objects. When you don't return new object references React doesn't consider the value to be different and bails on rerendering with updated values.

if (todo.id === id) {
  todo.completed = !todo.completed // <-- state mutation!
}
return todo // <-- same todo object reference

Solution

You need to also shallow copy any nested state you are updating.

handleChange(id) {
  this.setState((prevState) => ({
    todos: prevState.todos.map(todo => todo.id === id ? {
      ...todo, // <-- shallow copy todo
      completed: !todo.completed, // <-- update completed property
    } : todo)
  });
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.