Checkbox status does not change in react

Viewed 920

I have a quite simple question. Can me someone tell, why the status of the checkboxes doesn't change? The booleans in check change, but not the status of the checkboxes.

function KP() {
  const [name] = useState(["1", "2"]);
  const [check, setCheck] = useState([true, false]);

  const handleChange = (event) => {
    const { id, checked } = event.target;
    const index = name.indexOf(id);
    var temp = check;
    temp[index] = checked;
    setCheck(temp);
  };

  return (
    <div>
      {name.map((n, index) => {
        return (
          <div>
            <p>{n}</p>
            <input type="checkbox" checked={check[index]} onChange={handleChange} id={n} key={n}/>
          </div>
        );
      })}

    </div>
  );
}
4 Answers

this problem is so usual. React is not a simple appender to DOM. Use defaultChecked instead of checked.

You're using the same array(var temp = check). So the component will not rerender.

const handleChange = (event) => {
  const { id, checked } = event.target;
  const index = name.indexOf(id);
  setCheck(prevChecks => {
      const newChecks = [...prevChecks];
      newChecks[index] = checked;
      return newChecks;
  });
};

Because you're using the same reference(var temp = check;) to update state(check).

Try this

const handleChange = (event) => {
    const { id, checked } = event.target;
    const index = name.indexOf(id);
    check[index] = checked;
    setCheck([...check]);
};

Demo link here

I believe you have used an extra name array state in your code. I see no use case of this at all.

You can try this code and add ids into your object which contains status checked of checkboxes :) This is more performant code and uses less memory.

Here is the Full Code Demo:

const {useState, useEffect} = React;

function App() {
  const [check, setCheck] = useState([
    { id: 1, checked: true },
    { id: 2, checked: false }
  ]);

  const handleChange = (id) => {
    const updatedItems = check.map((item) => {
      if (item.id === id) {
        item["checked"] = !item["checked"];
        return item;
      }

      return item;
    });

    setCheck(updatedItems);
  };

  return (
    <div>
      {check.map((item, index) => {
        return (
          <div>
            <p>{item.id}</p>
            <input
              type="checkbox"
              checked={item["checked"]}
              onChange={() => handleChange(item.id)}
              id={item.id}
              key={item.id}
            />
          </div>
        );
      })}
    </div>
  );
}

ReactDOM.render(<App/>, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

Related