Ok, je vais essayer de faire ça rapidement car ça DEVRAIT être une solution facile ...
J'ai lu un tas de questions similaires et la réponse semble assez évidente. Rien que je n'aurais jamais à chercher en premier lieu! Mais ... j'ai une erreur que je n'arrive pas à comprendre comment réparer ou pourquoi cela se produit.
Comme suit:
class NightlifeTypes extends Component {
constructor(props) {
super(props);
this.state = {
barClubLounge: false,
seeTheTown: true,
eventsEntertainment: true,
familyFriendlyOnly: false
}
this.handleOnChange = this.handleOnChange.bind(this);
}
handleOnChange = (event) => {
if(event.target.className == "barClubLounge") {
this.setState({barClubLounge: event.target.checked});
console.log(event.target.checked)
console.log(this.state.barClubLounge)
}
}
render() {
return (
<input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/>
)
}
Plus de code entoure cela, mais c'est là que réside mon problème. Devrait fonctionner, non?
J'ai également essayé ceci:
handleOnChange = (event) => {
if(event.target.className == "barClubLounge") {
this.setState({barClubLounge: !this.state.barClubLounge});
console.log(event.target.checked)
console.log(this.state.barClubLounge)
}
J'ai donc ces deux console.log()
, les deux devraient être les mêmes. Je configure littéralement l'état pour qu'il soit le même que le event.target.checked
Dans la ligne au-dessus!
Mais cela renvoie toujours le contraire de ce qu'il devrait.
Il en va de même lorsque j'utilise !this.state.barClubLounge
; S'il commence faux, lors de mon premier clic, il reste faux, même si la case à cocher est cochée ou non est basée sur l'état !!
C'est un paradoxe fou et je n'ai aucune idée de ce qui se passe, aidez-moi!
La raison est setState est asynchrone , vous ne pouvez pas vous attendre à la valeur mise à jour state
juste après la setState
, si vous voulez vérifier la valeur, utilisez une méthode callback
. Passez une méthode en tant que rappel qui sera exécutée une fois que le setState
aura terminé sa tâche.
Pourquoi setState est asynchrone?
En effet, setState
modifie le state
et provoque un nouveau rendu. Cela peut être une opération coûteuse et la rendre synchronous
peut laisser le navigateur ne pas répondre. Ainsi, les appels setState
sont asynchronous
ainsi que groupés pour une meilleure expérience et performances de l'interface utilisateur.
De Doc:
setState () ne mute pas immédiatement this.state mais crée une transition d'état en attente. Accéder à this.state après avoir appelé cette méthode peut potentiellement renvoyer la valeur existante. Il n'y a aucune garantie de fonctionnement synchrone des appels vers setState et les appels peuvent être groupés pour des gains de performances.
Utilisation de la méthode de rappel avec setState:
Pour vérifier la valeur state
mise à jour juste après la setState
, utilisez une méthode de rappel comme celle-ci:
setState({ key: value }, () => {
console.log('updated state value', this.state.key)
})
Vérifie ça:
class NightlifeTypes extends React.Component {
constructor(props) {
super(props);
this.state = {
barClubLounge: false,
seeTheTown: true,
eventsEntertainment: true,
familyFriendlyOnly: false
}
}
handleOnChange = (event) => { // Arrow function binds `this`
let value = event.target.checked;
if(event.target.className == "barClubLounge") {
this.setState({ barClubLounge: value}, () => { //here
console.log(value);
console.log(this.state.barClubLounge);
//both will print same value
});
}
}
render() {
return (
<input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/>
)
}
}
ReactDOM.render(<NightlifeTypes/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
Puisque setState est une fonction asynchrone. Cela signifie qu'après avoir appelé la variable d'état setState ne change pas immédiatement. Donc, si vous souhaitez effectuer d'autres actions immédiatement après avoir changé l'état, vous devez utiliser la méthode de rappel de setstate dans votre fonction de mise à jour setState.
handleOnChange = (event) => {
let inputState = event.target.checked;
if(event.target.className == "barClubLounge") {
this.setState({ barClubLounge: inputState}, () => { //here
console.log(this.state.barClubLounge);
//here you can call other functions which use this state
variable //
});
}
}
Cela est dû à la conception en raison de considérations de performances. setState in React est une fonction garantie pour restituer Component, qui est un processus CPU coûteux. En tant que tel, ses concepteurs ont voulu optimiser en rassemblant plusieurs actions de rendu dans un, donc setState est asynchrone.