Mapeador de dados Javascript / React
Minha solução para implementar um status (string) combinando dois outros. Eu preciso declarar uma função que leva dois parâmetros (duas strings) e precisa retornar outro baseado na combinação dessas duas strings. Por ex:
carStatus(status, secondaryStatus) => string
em que secondaryStatus pode ter várias opções. Estou usando uma instrução if / else if que retorna um terceiro status de que preciso. Por exemplo, quando o status é 'ABERTO' e o status secundário é 'pagamento1' ou 'pagamento2' ou 'pagamento3', a função deve retornar uma nova string (status) como 'CONFIRMADO'. Então, minha solução neste momento seria algo assim:
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>
Em div deve ser processado como 'CONFIRMADO'.
Na minha implementação, terei que escrever outras 5 instruções if ... então talvez haja uma maneira mais limpa de implementar isso.
Qualquer ajuda será apreciada.
Respostas
Bug de condição Sua implementação atual tem um bug. Suas linhas como essas têm o problema:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
JavaScript possui apenas operadores unários, operadores binários e um único operador ternário. Todos os operadores usados acima são operadores binários; duas expressões serão avaliadas em uma única expressão até que uma única seja deixada. Como ===tem precedência de operador maior que ||, seu código é equivalente a:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
(trueOrFalse || 'payment2' || 'payment3')
Os payment2e payment3não são comparados secondaryStatus, e se secondaryStatusnão forem payment1, toda a expressão será avaliada como 'payment2'um valor verdadeiro (porque ||será avaliado como o segundo valor se o primeiro for falsey):
// || operates left-to-right:
(trueOrFalse || 'payment2' || 'payment3')
((false || 'payment2') || 'payment3')
(('payment2') || 'payment3')
// payment2 is truthy, so the `||` evaluates to it:
('payment2')
Para corrigir a lógica, use uma matriz em vez disso e verifique o status em relação a cada elemento da matriz.
Erro de digitação? Você tem (secondaryStatus === 'payment2' || 'payment5' || 'payment5'), com payment5repetido duas vezes. Você quis dizer outra coisa, como payment9?
Os nomes carStatus não contêm o status do carro, como pareceria conter; é uma função que, quando chamada, retorna o status do carro. Ele também usa um statusparâmetro nomeado de maneira semelhante e confusa . Chame-os de outra coisa, se possível: talvez getCarStatuse qualquer coisa mais específica que o statusparâmetro represente. Talvez chamar secondaryStatus: paymentType.
DRY Você também deseja tornar o código mais DRY, o que se encaixa bem com a ideia de usar arrays. Você pode usar um objeto, cujas chaves são o status necessário e cujos valores são os secondaryStatusvalores possíveis , bem como o valor de retorno, se secondaryStatusfor encontrado.
Além disso, como todas as strings de pagamento terminam em um número, e esse número é a única coisa que muda, use esse número para configurar o objeto de configuração em vez das paymentstrings completas :
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 ao 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 de componente Parece que você está usando um componente de classe. React recomenda que você experimente usar componentes funcionais em um novo código; eles dizem que são um pouco mais fáceis de trabalhar e entender do que componentes baseados em classe na maioria das circunstâncias, e eu concordo. Tente usar componentes funcionais, se ainda não o fez, talvez goste deles.