Mappatore dati Javascript / React
La mia soluzione per implementare uno stato (stringa) combinando altri due. Devo dichiarare una funzione che accetta due parametri (due stringhe) e deve restituirne un altro in base alla combinazione di queste due stringhe. Ad esempio:
carStatus(status, secondaryStatus) => string
dove secondarioStatus può avere più opzioni. Sto usando un'istruzione if / else if che restituisce un terzo stato di cui ho bisogno. Ad esempio, quando lo stato è "APERTO" e secondarioStato è "pagamento1" o "pagamento2" o "pagamento3", la funzione deve restituire una nuova stringa (stato) come "CONFERMATO". Quindi, la mia soluzione in questo momento sarebbe qualcosa del genere:
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 deve essere reso "CONFERMATO".
Nella mia implementazione, dovrò scrivere penso che altre 5 istruzioni if .. quindi forse c'è un modo più pulito per implementarlo.
Qualsiasi aiuto sarà apprezzato.
Risposte
Condizione bug La tua attuale implementazione ha un bug. Le tue linee come queste hanno il problema:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
JavaScript ha solo operatori unari, operatori binari e un singolo operatore ternario. Tutti gli operatori usati sopra sono operatori binari; due espressioni verranno valutate in una singola espressione finché non ne rimane una sola. Poiché ===ha una precedenza operatore maggiore di ||, il tuo codice è equivalente a:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
(trueOrFalse || 'payment2' || 'payment3')
I payment2e payment3non vengono confrontati con secondaryStatus, e in caso secondaryStatuscontrario payment1, l'intera espressione 'payment2'restituirà un valore vero (perché ||valuterà il secondo valore se il primo è falso):
// || operates left-to-right:
(trueOrFalse || 'payment2' || 'payment3')
((false || 'payment2') || 'payment3')
(('payment2') || 'payment3')
// payment2 is truthy, so the `||` evaluates to it:
('payment2')
Per correggere la logica, utilizzare invece un array e controllare lo stato rispetto a ciascun elemento dell'array.
Errore di battitura? Lei ha (secondaryStatus === 'payment2' || 'payment5' || 'payment5'), con payment5ripetute due volte. Intendevi qualcos'altro, come payment9?
I nomi carStatus non contengono lo stato dell'auto, poiché sembrerebbe contenere; è una funzione che, se chiamata, restituisce lo stato dell'auto. Richiede anche un statusparametro dal nome simile a confusione . Chiamali qualcos'altro, se possibile: forse getCarStatuse qualunque cosa più specifica statusrappresentata dal parametro. Forse chiamare secondaryStatus: paymentType.
DRY Vuoi anche rendere il codice più DRY, che si adatta bene all'idea di usare invece gli array. È possibile utilizzare un oggetto le cui chiavi sono lo stato richiesto e i cui valori sono i secondaryStatusvalori possibili , nonché il valore restituito se secondaryStatusviene trovato.
Inoltre, poiché tutte le stringhe di pagamento terminano con un numero e quel numero è l'unica cosa che cambia, usa quel numero per impostare l'oggetto di configurazione invece delle paymentstringhe complete :
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;
}
}
}
Snippet dal vivo:
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')
);
Tipo di componente Sembra che tu stia utilizzando un componente di classe. React consiglia di provare a utilizzare componenti funzionali nel nuovo codice; dicono che sono un po 'più facili da lavorare e da capire rispetto ai componenti basati sulla classe nella maggior parte delle circostanze, e sono d'accordo. Prova invece a utilizzare componenti funzionali, se non l'hai già fatto, potrebbero piacerti.