Mario
Mario

Reputation: 107

Checkbox does not want to check or uncheck after clicking

Iterates on the todos array. Objects inside have the isChecked property. If isChecked === true marks the checkbox, ifisChecked === false the checkbox is uncheckbox. When I click on the checkbox. I can't mark or uncheckbox

Demo here: https://stackblitz.com/edit/react-ds9rsd

class App extends Component {
  constructor() {
    super();
    this.state = {
      todos: [
        {
          name:'A',
          id: 1,
          isChecked: true      
        },
         {
          name:'B',
          id: 2,
          isChecked: false     
        },
         {
          name:'C',
          id: 3,
          isChecked: true      
        }
      ]
    };
  }

  checked = (e) => {
    console.log(e.target.checked)
  }

  render() {
    return (
      <div>
        {this.state.todos.map((todo, index) => {
          return <input type="checkbox" checked={todo.isChecked} onChange={(e) => this.checked(e)}/>
        })}   
      </div>
    );
  }
}

Upvotes: 1

Views: 84

Answers (3)

Carlene
Carlene

Reputation: 357

You will need to add a function and call it for each checkbox

import React, { Component } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";

class App extends Component {
  constructor() {
    super();
    this.state = {
      todos: [
        {
          name: "A",
          id: 1,
          isChecked: true
        },
        {
          name: "B",
          id: 2,
          isChecked: false
        },
        {
          name: "C",
          id: 3,
          isChecked: true
        }
      ]
    };
  }

  checked = index => {
    /** get the current state */
    let _todos = this.state.todos;
    /** assign opposite value: true to false or false to true */
    _todos[index].isChecked = !_todos[index].isChecked;
    /** update state */
    this.setState({ todos: _todos });
  };

  render() {
    return (
      <div>
        {this.state.todos.map((todo, index) => {
          /** call the function passing the index value */
          return (
            <input
              label={todo.name}
              type="checkbox"
              checked={todo.isChecked}
              onChange={this.checked.bind(this, index)}
            />
          );
        })}
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

Upvotes: 0

Riccardo Gai
Riccardo Gai

Reputation: 421

A possibile solution could be updating the render function like this:

render() {
  return (
    <div>
      {this.state.todos.map((todo, index) => {
        return <input label={todo.name} type="checkbox" checked={todo.isChecked} 
        onChange={(e) => this.checked(todo)}/>
      })}   
    </div>
  );
}

and the checked method like this:

checked = (e) => {
  this.setState(state => {
    const list = state.todos.map((item) => {
      if (item.name === e.name) {
        return item.isChecked = !item.isChecked;
      } else {
        return item;
      }
    });
    return {
      list,
    };
  });
}

Upvotes: 0

Monika
Monika

Reputation: 195

In checked() function you are just logging the value. Instead of that you need to do setState() to save new state.

Upvotes: 2

Related Questions