Les boutons que je crée en utilisant ci-dessous semblent être en retard dans la valeur selectedButtonIdx .
Le toggleSelected n'est-il pas terminé au moment où getClass est appelé?
function ButtonGroup(props) {
const [selectedButtonIdx,setIdx]=useState(props.loadCurrentAsIndex);
const toggleSelected = (e) => {
setIdx(parseInt(e.target.dataset.index));
props.onclick(e);
};
const getClass = (index) => {
return (selectedButtonIdx === index) ? classnames('current', props.btnClass)
: classnames(props.btnClass)
};
let buttons = props.buttons.map((b, idx) => <Button key={idx} value={b.value} index={idx} text={b.text}
onclick={e => toggleSelected(e)}
btnClass={getClass(idx)}/>);
return (
<div>
{buttons}
</div>
);
}
Chaque clic doit montrer à l'utilisateur sur quel bouton du groupe a été cliqué en changeant sa classe.
3 Réponses :
La fonction setIdx, renvoyée par useState est asynchrone, cela signifie qu'elle ne sera peut-être pas terminée au moment où vous exécuterez votre prochaine fonction (comme vous l'avez deviné).
Jetez un œil à useEffect , il vous permet de spécifier une fonction à exécutée une fois qu'un élément dans votre état change, cette méthode garantira que vos fonctions sont appelées dans le bon ordre.
En regardant ceci,
const Button = (props) => {
return <button text={props.text} data-index={props.index} onClick={props.onclick} className={props.btnClass}>{props.value}</button>
}
Button est votre composant personnalisé,
Deux choses à noter ici,
onclick ( c est petit), dans votre composant réel, il devrait être onClick = {props.onclick}
e.target.dataset.index , pour travailler avec dataset nous devrions avoir un attribut avec le préfixe data- . Ainsi, votre index doit être data-index dans votre composant réel. Donc, enfin, votre composant Button devrait être,
<Button
key={idx}
value={b.value}
index={idx}
text={b.text}
onclick={e => toggleSelected(e)}
btnClass={getClass(idx)}
/>
Pour le moment, je ne vois rien de mal ici.
Comment ça marche:
onClick est lié setIdx déclenchant un nouveau rendu selectedButtonIdx est utilisé pour le rendu (et pour l'appel getClass également) Vous voyez, il n'y a aucune raison de s'inquiéter si setIdx est une fonction de synchronisation ou asynchrone.
Cela est probablement dû au fait que
useStateest asynchrone comme répondu ici .Bonjour bonney, lisez ceci - stackoverflow.com/help/someone-answers , et essayez de fermer la question.