'React - How To Uncheck All Checkboxes At Once

I have attempted calling my setItems functions and using a spread operator on items and/or allItems to map over and set item.checked to false but I'm stumped. I appreciate any feedback and if I have posted incorrectly please let me know. Everything renders correctly upon loading page. I can changed object property bools manually and they update accordingly. I am just trying to figure a button that will reset them all back to false.

const Checklist = () => {
const allItems = [
 { name: "Pan", checked: false },
 { name: "Spatula", checked: false },
 { name: "Bread", checked: false },
 { name: "Butter", checked: false },
 { name: "Cheese", checked: false },
];

const [items, setItems] = useState(allItems);

return (
<div className="checklist">
  <div>
    <table>
      <tbody>
        {items.map((item) => {
          return (
            <tr key={item.name}>
              <td>
                <input
                  type="checkbox"
                  defaultChecked={item.checked}
                  onChange={() => !item.checked}
                  onClick={() => console.log(item.checked)}
                />
              </td>
              <td>{item.name}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  </div>
  <br />
  <button type="submit" id="checkbox-clear-btn">
    Uncheck All
  </button>
</div>
);
};


Solution 1:[1]

The below may be one possible solution that achieves the objective.

Code Snippet

const {useState} = React;

const Checklist = () => {
  const allItems = [
   { name: "Pan", checked: false },
   { name: "Spatula", checked: false },
   { name: "Bread", checked: false },
   { name: "Butter", checked: false },
   { name: "Cheese", checked: false },
  ];
  // add an 'id' to each object to help identify array index
  const [items, setItems] = useState([...allItems.map((x, id) => ({id, ...x}))]);
  // handle check & uncheck all buttons click
  const handleClick = e => {
    if (['check', 'uncheck'].includes(e.target.name)) {
      // determine whether to update 'checked' to true or false
      const updateChecked = e.target.name === 'check';
      setItems(prev => ([
        ...prev.map(({checked, ...rest}) => ({...rest, checked: updateChecked}))
      ]));
    }
  };

  return (
  <div className="checklist">
    <div>
      <table>
        <tbody>
          {items.map((item) => {
            return (
              <tr key={item.name}>
                <td>
                  <input
                    type="checkbox"
                    checked={item.checked}
                    onChange={() => {
                      // checkbox has changed
                      // track using item.id and flip 'checked'
                      const curr = items;
                      curr[item.id].checked = !(curr[item.id].checked);
                      setItems([...curr]);
                    }}
                  />
                </td>
                <td>{item.name}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
    <br />
    <button name="check" id="checkbox-clear-btn" onClick={handleClick}>
      Check All
    </button>
    &emsp; &emsp;
    <button name="uncheck" id="checkbox-clear-btn" onClick={handleClick}>
      Uncheck All
    </button>
  </div>
  );
};

ReactDOM.render(
  <div>
    DEMO
    <Checklist />
  </div>,
  document.getElementById("rd")
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

Explanation

Description is added inline in the above code-snippet.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jsN00b