Form check box not updating state on uncheck

Viewed 189

I have form check box where the values of checked boxed are returned as json, if i uncheck the json is still showing the value of the checked value

onChange function

const setApproveDeclineValues = (e) => {
    setChecked(!checked);
    setIsChecked({ ...isChecked, [e.target.name]: e.target.value });
    console.log(isChecked);
}

Form

<Form.Check
    type="checkbox"
    id={data.schudule_number}
    defaultChecked={checked}
    name={data.schudule_number}
    value={data.schudule_number}
    onChange={setApproveDeclineValues}
/>

useState

const [checked, setChecked] = useState(true);
const [isChecked, setIsChecked] = useState({});

output when checked

{11010: "11010", 11040: "11040"}

expected output if unchecked

{11010: "11010"}

And also how do i update the checked values on useEffect(); ? By defualt all the checkbox are selected, how do i get this values ? i am getting empty json

 {}

on page load

1 Answers

I don't think it fully solves it, I mean, works, but it's now scoped for each input. You would need some hight order state to gather this data I guess... But maybe would give some idea.

The pieces of code that looks like setState(s => !s) is, what I think its called, a dispatch function. useState receives the current state as a argument that you can use, rather than access the state itself (would cause a react warning or a infinite loop. I broke my chrome.)

here's a codesandbox with the code:

https://codesandbox.io/s/stack-form-check-box-not-updating-state-on-uncheck-muudh [edited to handle multiples inputs]

ps. I never used delete before, not sure how it works, if its safe, etc.

(and also pasted for posterity)

import { useEffect, useRef, useState } from "react";
import "./styles.css";

function Checkbox({ name, setChecks }) {
  const [checked, setChecked] = useState(true);
  const inputRef = useRef(null);

  useEffect(() => {
    if (checked) {
      setChecks((c) => ({
        ...c,
        [inputRef.current.name]: inputRef.current.value
      }));
    } else {
      setChecks((c) => {
        const newC = { ...c };
        delete newC[inputRef.current.name]; // but i think that set the value to false may be better. otherwise the problem that you had here may propagate in database or whatever
        return newC;
      });
    }
  }, [checked, setChecks]);

  return (
    <input
      ref={inputRef}
      type="checkbox"
      defaultChecked={checked} //this could be a prop too
      id={name}
      name={name}
      value={name}
      onChange={() => setChecked((c) => !c)}
    />
  );
}

export default function App() {
  const [checks, setChecks] = useState({});

  useEffect(() => {
    console.log(checks);
  }, [checks]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Checkbox name="one" setChecks={setChecks} />
      <Checkbox name="two" setChecks={setChecks} />
      <Checkbox name="three" setChecks={setChecks} />
    </div>
  );
}
Related