0

I don't understand checkboxes in ReactJS. I found this question but it has a ton of upvoted answers where everyone is doing something else. Some answers use checked={isCheckedState}, which however for me throws uncontrolled input error. Other use defaultChecked, which removes the uncontrolled error but then the checkbox won't change. Some have no value attribute but when I don't have that, the e.target.value always returns the string "on".

Can someone please explain to me how checkboxes REALLY should be handled in ReactJS?

const [checkBox, setCheckbox] = useState(false); //default unchecked


const handleCheckbox = (val) => {
    setCheckbox(!val); //toggle
    console.log(val, checkBox);
}

render(
            <input 
                id="check"
                type="checkbox"
                value={checkBox} //if I remove this, "val" always contains "on"
                defaultChecked={checkBox}
                onChange={e => handleCheckbox(e.target.value)} 
            />
);
user6329530
  • 596
  • 1
  • 7
  • 21

3 Answers3

1

you skipped the fact that they are not using e.target.value... :

<input 
    id="check"
    type="checkbox"
    checked={checkBox} //if I remove this, "val" always contains "on"
    onChange={e => handleCheckbox(!checkBox)} 
/>

in addition u can use checked instead of value like this:

onChange={e => handleCheckbox(e.target.checked)} 
adir abargil
  • 5,495
  • 3
  • 19
  • 29
1

This will help you understand how it works!

    const [checkBox, setCheckbox] = useState(false);

    useEffect(() => {
        console.log("Hey Checkbox Checked ?", checkBox);
    }, [checkBox]);

    const handleCheckbox = () => {
        setCheckbox(!checkBox);
    }

    return (
        <input
            id="check"
            type="checkbox"
            checked={checkBox}
            onChange={handleCheckbox}
        />
    );
A.R.SEIF
  • 865
  • 1
  • 7
  • 25
Veno
  • 433
  • 2
  • 14
  • Changing defaultChecked into checked causes uncontrolled input error to be thrown: Warning: A component is changing an uncontrolled input of type number to be controlled. BTW on a side note, if you don't plan to pass e to the handler function, you don't need e => and () and can just write onChange={handleCheckbox} – user6329530 Sep 30 '20 at 13:24
  • 1
    You can use both checked and defaultChecked in this case, whenever any value is changed, this will toggle the state, so as the value for checked and defaultChecked – Veno Sep 30 '20 at 13:27
  • Updated the unwanted callback function to my answer! – Veno Sep 30 '20 at 13:28
  • Yes but it still throws the error when I don't use defaultChecked – user6329530 Sep 30 '20 at 13:28
  • 1
    Does this solve you problem? [Solution](https://stackoverflow.com/questions/47012169/a-component-is-changing-an-uncontrolled-input-of-type-text-to-be-controlled-erro) – Veno Sep 30 '20 at 13:30
0

Each input box value will be stored in the state. If you have many, you could store these inside of an array, but since you just have one, you can store it in just a variable, in your case called 'checkBox'

Now come the updating part of it. What most people do is they just set the new to the opposite of the new state.

With State Hooks

onChange={() => setChecked(!checkBox)}

With Classes

onChange={() => this.setState({
      checkBox: !this.state.checkBox,
    });}

You can also use events

  const handleCheckbox = (event) => {
    if (event.target.value === "true") {
      setCheckbox(false); //toggle
    } else {
      setCheckbox(true); //toggle
    }
    console.log(event.target.value, checkBox);
  };

    
onChange={handleCheckbox} 

I recommend using state hooks if you are using a function

John Salzman
  • 500
  • 5
  • 14