Mappeur de données Javascript / React
Ma solution pour implémenter un statut (string) en combinant deux autres. J'ai besoin de déclarer une fonction qui prend deux paramètres (deux chaînes) et doit en renvoyer une autre basée sur la combinaison de ces deux chaînes. Par exemple:
carStatus(status, secondaryStatus) => string
où SecondaryStatus peut avoir plusieurs options. J'utilise une instruction if / else if qui renvoie un troisième statut dont j'ai besoin. Par exemple, lorsque le statut est «OUVERT» et que le statut secondaire est «paiement1» ou «paiement2» ou «paiement3», la fonction doit renvoyer une nouvelle chaîne (statut) comme «CONFIRMÉ». Donc, ma solution en ce moment serait quelque chose comme ceci:
carStatus = (status, secondaryStatus) => {
if(status === 'OPEN' && (secondaryStatus === 'payment1' || 'payment2' || 'payment3')){
return 'CONFIRMED';
} else if(status === 'CANCELLED' && (secondaryStatus === 'payment4' || 'payment5' || 'payment6')){
return 'REMOVED';
} else if(status === 'REVIEW' && (secondaryStatus === 'payment2' || 'payment5' || 'payment5')){
return 'CHECKED';
}
}
<div>carStatus('OPEN', 'payment1')</div>
In div doit être rendu 'CONFIRMED'.
Dans mon implémentation, je vais devoir écrire je pense que 5 autres instructions if .. alors peut-être qu'il y a une manière plus propre de l'implémenter.
Toute aide serait appréciée.
Réponses
Bogue de condition Votre implémentation actuelle a un bogue. Vos lignes comme celles-ci ont le problème:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
JavaScript n'a que des opérateurs unaires, des opérateurs binaires et un seul opérateur ternaire. Tous les opérateurs utilisés ci-dessus sont des opérateurs binaires; deux expressions seront évaluées en une seule expression jusqu'à ce qu'il n'en reste qu'une seule. Puisque ===a une priorité d'opérateur plus élevée que ||, votre code est équivalent à:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
(trueOrFalse || 'payment2' || 'payment3')
Les payment2et payment3ne sont pas comparés secondaryStatus, et si ce secondaryStatusn'est pas le cas payment1, l'expression entière sera évaluée à 'payment2'une valeur de vérité (car elle ||sera évaluée à la deuxième valeur si la première est fausse):
// || operates left-to-right:
(trueOrFalse || 'payment2' || 'payment3')
((false || 'payment2') || 'payment3')
(('payment2') || 'payment3')
// payment2 is truthy, so the `||` evaluates to it:
('payment2')
Pour corriger la logique, utilisez plutôt un tableau et vérifiez l'état par rapport à chaque élément du tableau.
Faute de frappe? Vous avez (secondaryStatus === 'payment2' || 'payment5' || 'payment5'), avec payment5répété deux fois. Vouliez-vous dire autre chose, comme payment9?
Les noms carStatus ne contiennent pas le statut de la voiture, comme cela semblerait le contenir; c'est une fonction qui, lorsqu'elle est appelée, renvoie l'état de la voiture. Il prend également un statusparamètre nommé de manière confuse . Appelez-les quelque chose d'autre, si cela est possible: peut getCarStatus- être et quelle que soit la chose plus spécifique que le statusparamètre représente. Peut - être appeler secondaryStatus: paymentType.
DRY Vous souhaitez également rendre le code plus DRY, ce qui correspond bien à l'idée d'utiliser des tableaux à la place. Vous pouvez utiliser un objet, dont les clés correspondent à l'état requis et dont les valeurs sont les secondaryStatusvaleurs possibles ainsi que la valeur de retour si le secondaryStatus.
De plus, comme toutes les chaînes de paiement se terminent par un nombre, et que ce numéro est la seule chose qui change, utilisez ce numéro pour configurer l'objet de configuration au lieu des paymentchaînes complètes :
const statusOptions = {
OPEN: { paymentNumbers: [1, 2, 3], status: 'CONFIRMED' },
CANCELLED: { paymentNumbers: [4, 5, 6], status: 'REMOVED' },
REVIEW: { paymentNumbers: [2, 5], status: 'CHECKED' },
};
// ...
getCarStatus = (status, paymentType) => {
const possibleOption = statusOptions[status];
if (possibleOption) {
const paymentNumber = Number(paymentType.match(/\d+$/)[0]);
if (possibleOption.paymentNumbers.includes(paymentNumber)) {
return possibleOption.status;
}
}
}
Extrait en direct:
const statusOptions = {
OPEN: { paymentNumbers: [1, 2, 3], status: 'CONFIRMED' },
CANCELLED: { paymentNumbers: [4, 5, 6], status: 'REMOVED' },
REVIEW: { paymentNumbers: [2, 5], status: 'CHECKED' },
};
// ...
getCarStatus = (status, paymentType) => {
const possibleOption = statusOptions[status];
if (possibleOption) {
const paymentNumber = Number(paymentType.match(/\d+$/)[0]);
if (possibleOption.paymentNumbers.includes(paymentNumber)) {
return possibleOption.status;
}
}
};
console.log(
getCarStatus('OPEN', 'payment3'),
getCarStatus('REVIEW', 'payment2')
);
Type de composant Il semble que vous utilisiez un composant de classe. React vous recommande d'essayer d'utiliser des composants fonctionnels dans un nouveau code; ils disent qu'ils sont un peu plus faciles à utiliser et à comprendre que les composants basés sur la classe dans la plupart des cas, et je suis d'accord. Essayez plutôt d'utiliser des composants fonctionnels, si vous ne l'avez pas déjà fait, vous pourriez les aimer.