This partly is because you are logging immediately after the set state. React does not immediately update the value, its flushed later at the end of the call stack and becomes what you expect on the next rerender.
More info: https://beta.reactjs.org/apis/react/useState#ive-updated-the-state-but-logging-gives-me-the-old-value
What you need to do depends on if the <input>
is controlled or not. Its controlled if you pass the checked
prop to it and uncontrolled if you do not pass it.
For controlled use:
// You also need to ensure your default state has all the
//names of each checkbox rendered from the beginning and they are
// set to false. THIS IS CRUCIAL IN THIS PATTERN!
// Or e.target.checked would be undefined.
// e.g.
//
// const [checked, setChecked] = useState({
// name1: false,
// name2: false,
// name3: false,
// ... // etc
// })
const handleChange = (e) => {
const { name, checked} = e.target;
setChecked((prevState) => {
return {
...prevState,
[name]: checked
};
});
};
// Input must be bound like
// <input name="your-name" onChange={handleChange} checked={this.state.checked["your-name"]} />
For uncontrolled use:
const handleClick = () => {
const { name } = e.target;
setChecked((prevState) => {
return {
...prevState,
[name]: !Boolean(prevState[name])
};
});
};
// Input must be bound like
// <input name="your-name" onClick={handleChange} defaultChecked={false} />