I have just found a stray event.preventDefault()
that was breaking my checkboxes' onChange
handler:
import { Component } from 'react';
class App extends Component {
constructor(props) {
super(props)
this.state = {
accepted: false
}
}
changeChecked = (event) => {
this.setState((state) => ({
accepted : !state.accepted
}));
event.preventDefault(); // <- this very bad
}
render() {
return (
<input
type="checkbox"
onChange={this.changeChecked}
checked={this.state.accepted}
/>
);
}
}
export default App;
The resulting behaviour is a correctly updated state on first click, but the checkbox only changes to its 'checked' appearance on the next rerender, eg. a second click.
Why is that? Isn't it the point of controlled components to work independently from browser events?
Someone explaining this to me would definitely ease the pain of hours spent boiling down my complex use case. Thank you!
Update: Here's a quick Codepen example demonstrating the odd behaviour.
I included an 'unprevented checkbox' and one with a prevented onClick
event as comparison.
Notice how the one with prevented onChange
switches its appearance to its actual state as soon as I click a different checkbox.