Je voudrais demander pourquoi mon état ne change pas lorsque je fais un événement onclick. J'ai cherché il y a quelque temps que je devais lier la fonction onclick dans le constructeur, mais l'état ne se met toujours pas à jour. Voici mon code:
import React from 'react';
import Grid from 'react-bootstrap/lib/Grid';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
import BoardAddModal from 'components/board/BoardAddModal.jsx';
import style from 'styles/boarditem.css';
class BoardAdd extends React.Component {
constructor(props){
super(props);
this.state = {
boardAddModalShow: false
}
this.openAddBoardModal = this.openAddBoardModal.bind(this);
}
openAddBoardModal(){
this.setState({ boardAddModalShow: true });
// After setting a new state it still return a false value
console.log(this.state.boardAddModalShow);
}
render() {
return (
<Col lg={3}>
<a href="javascript:;" className={style.boardItemAdd} onClick={this.openAddBoardModal}>
<div className={[style.boardItemContainer,style.boardItemGray].join(' ')}>
Create New Board
</div>
</a>
</Col>
)
}
}
export default BoardAdd
javascript
reactjs
ecmascript-6
Sydney Loteria
la source
la source
setState
ne retourne pas une promesse. Si cela fonctionnait, cela ne fonctionnait que parce que celaawait
introduisait un "tick" asynchrone dans la fonction, et il est arrivé que la mise à jour de l'état soit traitée pendant ce tick. Ce n'est pas garanti. Comme le dit cette réponse , vous devez utiliser le rappel d'achèvement (si vous avez vraiment besoin de faire quelque chose après la mise à jour de l'état, ce qui est inhabituel; normalement, vous voulez simplement effectuer un nouveau rendu, ce qui se produit automatiquement).Réponses:
Ce rappel est vraiment compliqué. Utilisez simplement async await à la place:
la source
setState
ne rend pas une promesse.setState
ne renvoie pas de promesse, donc il ne faut PAS l'attendre. Cela dit, je pense que je peux voir pourquoi cela fonctionne pour certaines personnes, car await met le fonctionnement interne de setState sur la pile d'appels avant le reste de la fonction, donc il est traité en premier, et semble donc que l'état a été ensemble. Si setState avait ou implémentait de nouveaux appels asynchrones, cette réponse échouerait.Pour implémenter cette fonction correctement, vous pouvez utiliser ceci:await new Promise(resolve => this.setState({ boardAddModalShow: true }, () => resolve()))
async this.setState({})
résolu mon problème? Nous avions du code fonctionnel, des développements supplémentaires ont été effectués mais rien n'a changé cette partie de l'application. Seul l'un des deux objets de setState a été mis à jour, ce qui rend la fonctionnalité renvoyée de manière asynchrone et maintenant les deux objets sont correctement mis à jour. Je n'ai aucune idée de ce qui n'allait pas.Votre état a besoin d'un certain temps pour muter, et comme
console.log(this.state.boardAddModalShow)
s'exécute avant que l'état mute, vous obtenez la valeur précédente en sortie. Vous devez donc écrire la console dans le rappel de lasetState
fonctionsetState
est asynchrone. Cela signifie que vous ne pouvez pas l'appeler sur une ligne et supposer que l'état a changé sur la suivante.Selon les documents React
Pourquoi feraient-ils
setState
asynchronela source
Prend heureusement
setState()
un rappel. Et c'est là que nous obtenons l'état mis à jour.Prenons cet exemple.
Ainsi, lorsque le rappel se déclenche, this.state est l'état mis à jour.
Vous pouvez obtenir des
mutated/updated
données en rappel.la source
initMap()
, par exempleComme setSatate est une fonction asynchrone, vous devez donc consolider l'état comme un rappel comme celui-ci.
la source
setState()
ne met pas toujours immédiatement à jour le composant. Il peut grouper ou reporter la mise à jour à plus tard. Cela rend la lecture de this.state juste après avoir appelésetState()
un piège potentiel. À la place, utilisezcomponentDidUpdate
ou unsetState
callback (setState(updater, callback)
), dont l'un ou l'autre est garanti de se déclencher une fois la mise à jour appliquée. Si vous devez définir l'état en fonction de l'état précédent, lisez l'argument du programme de mise à jour ci-dessous.setState()
mènera toujours à un nouveau rendu à moins qu'il neshouldComponentUpdate()
renvoie false. Si des objets mutables sont utilisés et que la logique de rendu conditionnel ne peut pas être implémentée dansshouldComponentUpdate()
, un appelsetState()
uniquement lorsque le nouvel état diffère de l'état précédent évitera les rendus inutiles.Le premier argument est une fonction de mise à jour avec la signature:
state
est une référence à l'état du composant au moment où la modification est appliquée. Il ne doit pas être directement muté. Au lieu de cela, les changements doivent être représentés en construisant un nouvel objet basé sur l'entrée de l'état et des accessoires. Par exemple, supposons que nous voulions incrémenter une valeur dans state par props.step:la source
Si vous souhaitez suivre l'état en cours de mise à jour ou non, une autre façon de faire la même chose est
De cette façon, vous pouvez appeler la méthode "_stateUpdated" chaque fois que vous essayez de mettre à jour l'état pour le débogage.
la source
setState()
est asynchrone. La meilleure façon de vérifier si l'état est en cours de mise à jour serait decomponentDidUpdate()
ne pas mettre unconsole.log(this.state.boardAddModalShow)
aprèsthis.setState({ boardAddModalShow: true })
.selon React Docs
la source
Selon React Docs
Exemple:
la source
Pour quiconque essaie de faire cela avec des crochets, vous en avez besoin
useEffect
.Production:
la source
lorsque j'exécutais le code et que je vérifiais ma sortie sur la console, cela montrait qu'il n'était pas défini. Après avoir cherché et trouvé quelque chose qui a fonctionné pour moi.
J'ai ajouté cette méthode dans mon code après constructor (). Découvrez le cycle de vie du workflow natif de réaction.
https://images.app.goo.gl/BVRAi4ea2P4LchqJ8
la source
la source
Oui car setState est une fonction asynchrone. La meilleure façon de définir l'état juste après avoir écrit l'état d'ensemble est d'utiliser Object.assign comme ceci: Par exemple, vous voulez définir une propriété isValid sur true, faites-le comme ceci
Vous pouvez accéder à l'état mis à jour juste après avoir écrit cette ligne.
la source