Trouvez ci-dessous des exemples de codes et une capture d'écran.
Deux questions:
Le compteur
ne se met pas à jour correctement, est-il permis d'écrire quelque chose comme setCounter ((prev) => {return {counter: prev.counter - value || 1 }});
?
setCounter (compteur + valeur || 1)
Quelle est la bonne manière pour cela
pour fonctionner, utilisez 1 dans les cas où une valeur réelle manque?
Trouvez ci-dessous des exemples de codes et de capture d'écran.
const Counter = (props) => { const [counter, setCounter] = useState(0); const handleCounterChange = (action, value) => { switch (action) { case "+": setCounter(counter + value || 1); break; case "-": setCounter(counter - value || 1); break; default: setCounter(counter + value || 1); break; } }; return ( <div className={classes.Counter}> <CounterOutput value={counter} /> <CounterControl label="+" clicked={() => handleCounterChange("+")} /> <CounterControl label="-" clicked={() => handleCounterChange("-")} /> <CounterControl label="+ 5" clicked={() => handleCounterChange("+", 5)} /> <CounterControl label="- 5" clicked={() => handleCounterChange("-", 5)} /> </div> ); }; export default Counter;
3 Réponses :
Le problème avec setCounter (compteur + valeur || 1);
est que JS essaiera d'abord de calculer compteur + valeur
puis le test booléen. Par exemple, si la valeur de votre compteur
est 1
et que vous soustrayez une valeur de 1
, le résultat est 0
, ce qui est faux, alors 1
sera sauvegardé comme nouvelle valeur du counter
. Ce n'est probablement pas ce que vous voulez.
const handleCounterChange = (action, value = 1) => { switch (action) { case "+": setCounter(counter => counter + value); break; case "-": setCounter(counter => counter - value); break; default: // ignore, i.e. don't update state at all break; } };
Vous pouvez cependant regrouper la priorité, c'est-à-dire counter + (value || 1)
.
const handleCounterChange = (action, value = 1) => { switch (action) { case "+": setCounter(counter => counter + value); break; case "-": setCounter(counter => counter - value); break; default: setCounter(counter => counter + value); break; } };
Si vous souhaitez simplement fournir une valeur par défaut de 1 pour valeur
, vous pouvez le faire dans la signature. Si la valeur
n'est pas définie, la valeur 1
lui sera attribuée. Et utilisez une mise à jour de l'état fonctionnel.
console.log(100 + (undefined || 1)); // 101
Une note complémentaire à propos de ce modèle de type "réducteur" est de renvoyer l'état existant si l'action n'est pas celle que vous gérez spécifiquement.
console.log(100 + undefined || 1); // expect 101 but result is 1 console.log(1 + -1 || 1); // expect 0 but result is 1
Ce n'est pas une réponse en soi, mais ne compliquez pas trop votre code avec cette fonction supplémentaire inutile. Votre logique est si simple, l'ajout de cette fonction supplémentaire la rend plus complexe à lire et ajoute une logique étrange (à quoi sert la valeur par défaut?)
const change = by => () => setCounter(count => count+by) return ( <div className={classes.Counter}> <CounterOutput value={counter} /> <CounterControl label="+" clicked={change(1)} /> <CounterControl label="-" clicked={change(-1)} /> <CounterControl label="+ 5" clicked={change(5)} /> <CounterControl label="- 5" clicked={change(-5)} /> </div> );
Si vous voulez le sécher un peu plus, vous pouvez faites toujours quelque chose comme ceci:
return ( <div className={classes.Counter}> <CounterOutput value={counter} /> <CounterControl label="+" clicked={() => setCounter(state => state+1)} /> <CounterControl label="-" clicked={() => setCounter(state => state-1)} /> <CounterControl label="+ 5" clicked={() => setCounter(state => state+5)} /> <CounterControl label="- 5" clicked={() => setCounter(state => state-5)} /> </div> );
Il y a quelques excellents refactors proposés ici. Je voudrais vraiment lire les suggestions et faire un refactor.
Quant à la cause de votre compteur imprévisible, en supposant que les arguments de clic entrent dans votre fonction de mise à jour d'état, il y a un problème d'ordre des opérations. Considérez cette situation.
non définie
De la façon dont le code ci-dessus est écrit, lorsque la valeur est non définie
, nous espère ajouter un nombre de valeur
à l'état compteur
. En raison de l'ordre des opérations, ce n'est pas ce qui se passe. Ce bogue se cache à la vue car souvent valeur
et compteur
sont tous les deux 1
, il semble donc que l'état ne change pas.
> counter + (value || 100) 101
Cette dernière déclaration dit "additionner le compteur plus undefined
" qui est NaN
et également faux. Le résultat dans ce cas sera toujours l'autre côté de l'instruction 'ou', 100
.
L'utilisation de parenthèses change l'ordre des opérations et crée le comportement souhaité. p>
> let value = undefined undefined > let counter = 1 undefined > counter + value || 100 100