Using React and Material UI checkbox
I'm trying to have a checkbox render a state change to a specific value when it is checked.
Everything is working properly, however only on the first 2 clicks of the checkbox the state doesn't update properly
const [waterChecked, setWaterChecked] = React.useState(true);
const [data, setData] = useState(null);
const handleChangeWater = (event) => {
setWaterChecked(event.target.checked);
if (waterChecked) {
setData([1, 2, 3, 4])
} else if (!waterChecked) {
setData([])
}
};
<ul>
<Checkbox
waterChecked={waterChecked}
onChange={handleChangeWater}
defaultChecked={false}
inputProps={{ 'aria-label': 'controlled' }}
/>
Water
</ul>
Putting a console.log(waterChcked) inside of my handleChangeWater function grants these outputs. After 5 clicks I get:
true, true, false, true, false
It works exactly as intended after the first 2 clicks, the only issue is the order is inverted because of the double true at the start.
for example 7 clicks of the checkbox outputs
true, true, false, true, false, true, false
etc..
Any advice would be greatly appreciated, I am new to react so please excuse any syntax prolems.
Thank you!
CodePudding user response:
setWaterChecked(event.target.checked)
sets the waterChecked
state asynchronously. Therefore, you can't use it to set the data
state afterward. Therefore, use event.target.checked
value to set the data
state as follows.
const [waterChecked, setWaterChecked] = React.useState(true);
const [data, setData] = useState(null);
const handleChangeWater = (event) => {
const checked = event.target.checked;
setWaterChecked(checked);
if (checked) {
setData([1, 2, 3, 4]);
} else {
setData([]);
}
};
<ul>
<Checkbox
waterChecked={waterChecked}
onChange={handleChangeWater}
defaultChecked={false}
inputProps={{ "aria-label": "controlled" }}
/>
Water
</ul>;
Or you can use useEffect
to keep track on waterChecked
state and do the necessary changes on data
state as follows.
const [waterChecked, setWaterChecked] = React.useState(true);
const [data, setData] = useState(null);
const handleChangeWater = (event) => {
setWaterChecked(event.target.checked);
};
useEffect(() => {
if (waterChecked) {
setData([1, 2, 3, 4]);
} else {
setData([]);
}
}, [waterChecked]);
<ul>
<Checkbox
waterChecked={waterChecked}
onChange={handleChangeWater}
defaultChecked={false}
inputProps={{ "aria-label": "controlled" }}
/>
Water
</ul>;