I know setState()
does not immediately mutate this.state
. So in the code below, checkbox is always unchecked after clicking the button. How to fix this?
handleClick = () => {
this.setState({tick: !this.state.tick})
}
render() {
return (
<button type='button' onClick={() => this.handleClick()} >
<input type="checkbox" value={this.state.tick} />
Tick here
</button>
)
}
I know setState()
does not immediately mutate this.state
. So in the code below, checkbox is always unchecked after clicking the button. How to fix this?
handleClick = () => {
this.setState({tick: !this.state.tick})
}
render() {
return (
<button type='button' onClick={() => this.handleClick()} >
<input type="checkbox" value={this.state.tick} />
Tick here
</button>
)
}
Share
Improve this question
asked Dec 18, 2018 at 3:31
lucahuylucahuy
8002 gold badges11 silver badges22 bronze badges
2 Answers
Reset to default 6use checked
instead of value
:
<input type="checkbox" checked={this.state.tick} />
from the spec:
checked
: Boolean; if present, the checkbox is currently toggled on
value
: The string to use as the value of the checkbox when submitting the form, if the checkbox is currently toggled on
ic3b3rg's answer highlights what needs to be changed in the code for the checkbox to work. I'm going to highlight a few other things that could be improved.
Checkbox check state should be controlled with
checked
attributeDon't declare your event handlers with arrow functions as it will create a new anonymous function during every single render. It's a good idea to bind a function to the class and pass it to the event handler.
Something like this
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
...
}
// render
<button type = 'button' onClick = {this.handleClick} >
- When you want to update state based on existing state value, it's usually not a good idea to call
this.state.key
directly in yoursetState
function assetState
is an async call and you can't exactly say what the value of your current state will be. Instead, if you usethis.setState((prevState, props) => ({})
callback, your state value will be updated based on what your existing state value was during invocation.
Change this
this.setState({tick: !this.state.tick})
to
this.setState((prevState, props) => ({
tick: !prevState.tick
}));
Here's a full working example
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
tick: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// when updating state values from existing state values
// you should use not use value: !this.state.value directly
this.setState((prevState, props) => ({
tick: !prevState.tick
}));
}
render() {
return (
<button type = 'button' onClick={this.handleClick} >
<input type = "checkbox" checked={this.state.tick} />Tick here
</button>
);
}
}
ReactDOM.render( <
Example / > ,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>