Javascript / React data mapper

Sep 26 2020

Solusi saya untuk menerapkan status (string) dari menggabungkan dua yang lain. Saya perlu mendeklarasikan fungsi yang mengambil dua params (dua string) dan perlu mengembalikan yang lain berdasarkan kombinasi kedua string tersebut. Misalnya:

carStatus(status, secondaryStatus) => string

di mana secondaryStatus dapat memiliki beberapa opsi. Saya menggunakan pernyataan if / else if yang mengembalikan status ketiga yang saya butuhkan. Misalnya ketika statusnya adalah 'OPEN' dan secondaryStatus adalah 'payment1' atau 'payment2' atau 'payment3', fungsi tersebut harus mengembalikan string baru (status) seperti 'CONFIRMED'. Jadi, solusi saya saat ini adalah seperti ini:

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>

Dalam div harus dirender 'DIKONFIRMASI'.

Dalam implementasinya, saya harus menulis 5 pernyataan if lainnya menurut saya .. jadi mungkin ada cara yang lebih bersih untuk mengimplementasikan ini.

Bantuan apa pun akan dihargai.

Jawaban

3 CertainPerformance Sep 26 2020 at 22:01

Kondisi bug Implementasi Anda saat ini memiliki bug. Baris Anda seperti ini bermasalah:

(secondaryStatus === 'payment1' || 'payment2' || 'payment3')

JavaScript hanya memiliki operator unary, operator biner, dan operator terner tunggal. Semua operator yang digunakan di atas adalah operator biner; dua ekspresi akan dievaluasi menjadi satu ekspresi hingga satu ekspresi tersisa. Karena ===memiliki operator prioritas yang lebih tinggi daripada ||, kode Anda setara dengan:

(secondaryStatus === 'payment1' || 'payment2' || 'payment3')

(trueOrFalse || 'payment2' || 'payment3')

The payment2dan payment3tidak dibandingkan dengan secondaryStatus, dan jika secondaryStatustidak payment1, seluruh ekspresi akan mengevaluasi 'payment2', nilai truthy (karena ||akan mengevaluasi dengan nilai kedua jika yang pertama adalah falsey):

// || operates left-to-right:

(trueOrFalse || 'payment2' || 'payment3')

((false || 'payment2') || 'payment3')

(('payment2') || 'payment3')

// payment2 is truthy, so the `||` evaluates to it:
('payment2')

Untuk memperbaiki logika, gunakan array sebagai gantinya, dan periksa status terhadap setiap elemen dalam array.

Salah ketik? Sudah (secondaryStatus === 'payment2' || 'payment5' || 'payment5'), dengan payment5diulang dua kali. Apakah maksud Anda sesuatu yang lain, seperti payment9?

Nama carStatus tidak memuat status mobil, karena kedengarannya mengandung; itu adalah fungsi yang, ketika dipanggil, mengembalikan status mobil. Ini juga mengambil statusparameter bernama mirip yang membingungkan . Sebut mereka sesuatu yang lain, jika memungkinkan: mungkin getCarStatusdan hal yang lebih spesifik yang statusdiwakili oleh parameter. Mungkin panggilan secondaryStatus: paymentType.

KERING Anda juga ingin membuat kode lebih KERING, yang cocok dengan gagasan menggunakan array. Anda mungkin menggunakan objek, yang kuncinya adalah status yang diperlukan, dan yang nilainya adalah nilai yang mungkin secondaryStatusserta nilai yang dikembalikan jika secondaryStatusditemukan.

Selain itu, karena semua string pembayaran diakhiri dengan angka, dan angka itu adalah satu-satunya yang berubah, gunakan angka itu untuk menyiapkan objek konfigurasi alih-alih paymentstring lengkap :

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;
        }
    }
}

Cuplikan langsung:

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')
);

Jenis komponen Sepertinya Anda menggunakan komponen kelas. React menganjurkan agar Anda mencoba menggunakan komponen fungsional dalam kode baru; mereka mengatakan bahwa mereka sedikit lebih mudah untuk dikerjakan dan dipahami daripada komponen berbasis kelas dalam banyak situasi, dan saya setuju. Coba gunakan komponen fungsional sebagai gantinya, jika Anda belum melakukannya, Anda mungkin menyukainya.