0

Can someone explain why this event is fired off twice?

Here is my mainContent Component

class MainContent 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) {
                console.log(!todo.completed)
                todo.completed = !todo.completed
            }
            return todo
        })
        console.log(updatedToDos)
        return {
            todos: updatedToDos
        }
    })
}


render() {
    const mainBodyStyles = {
        color: "#FF8C00",
        backgroundColor: "#fG7B02",
    }
    const todoItems = this.state.todos.map(item =>
        <TodoItem
        key={item.id}
        item={item}
        handleChange={this.handleChange}
        />)
    return (
    <div style={mainBodyStyles}>
        {todoItems}
    </div>
    )
}

here is my toDo component

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

}

When I click on a checkbox It runs the event function twice. I can't wrap my head around what I am doing wrong. Thanks in advance.

2 Answers2

1

It is expected that the state updaters are called twice in React.Strict mode. Refer to this answer Why is my function being called twice in React?

Update your handleChange function to below.

  handleChange(id) {
    const todos = [...this.state.todos];
    const newTodo = todos.map((todo) => {
      if (todo.id === id) {
        console.log(!todo.completed);
        todo.completed = !todo.completed;
      }
      return todo;
    });
    console.log(newTodo);
    this.setState({ todos: newTodo });
  }
Lokii
  • 402
  • 4
  • 14
0

I think, this is happening because this.setState call in App.js handleChange function is mutating or changing state of prevState

handleChange(id){    
    
    this.setState((prevState) => {            
              let updatedToDos  =   prevState.todos.map(
                todo  => {
                  let tempItem=Object.assign({}, todo);

                  if(tempItem.id === id) {
                    console.log("here");
                    tempItem.completed = !tempItem.completed                              
                  }
                  return tempItem; 
            }
          );

      return { todos:updatedToDos };
    });
  }
ProgIn
  • 181
  • 1
  • 6