Javascript / React Data Mapper

Sep 26 2020

Meine Lösung, um einen Status (String) aus der Kombination von zwei anderen zu implementieren. Ich muss eine Funktion deklarieren, die zwei Parameter (zwei Zeichenfolgen) akzeptiert und basierend auf der Kombination dieser beiden Zeichenfolgen eine weitere zurückgeben muss. Zum Beispiel:

carStatus(status, secondaryStatus) => string

Dabei kann SecondaryStatus mehrere Optionen haben. Ich verwende eine if / else if-Anweisung, die einen dritten Status zurückgibt, den ich benötige. Zum Beispiel, wenn der Status 'OPEN' ist und der sekundäre Status 'Zahlung1' oder 'Zahlung2' oder 'Zahlung3' ist, muss die Funktion eine neue Zeichenfolge (Status) wie 'BESTÄTIGT' zurückgeben. Meine Lösung in diesem Moment wäre also ungefähr so:

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 muss 'BESTÄTIGT' gerendert werden.

In meiner Implementierung muss ich schreiben, ich denke andere 5 if-Anweisungen. Vielleicht gibt es einen saubereren Weg, dies zu implementieren.

Jede Hilfe wird geschätzt.

Antworten

3 CertainPerformance Sep 26 2020 at 22:01

Bedingungsfehler Ihre aktuelle Implementierung hat einen Fehler. Ihre Zeilen wie diese haben das Problem:

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

JavaScript hat nur unäre Operatoren, binäre Operatoren und einen einzigen ternären Operator. Alle oben verwendeten Operatoren sind binäre Operatoren. Zwei Ausdrücke werden zu einem einzigen Ausdruck ausgewertet, bis ein einziger übrig bleibt. Da Ihr ===Operator eine höhere Priorität als der Operator hat ||, entspricht Ihr Code:

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

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

Die payment2und payment3werden nicht mit einem wahrheitsgemäßen Wert verglichen secondaryStatus, und wenn dies secondaryStatusnicht payment1der 'payment2'Fall ist , wird der gesamte Ausdruck mit einem wahrheitsgemäßen Wert ||bewertet (da der zweite Wert bewertet wird, wenn der erste falsch ist):

// || operates left-to-right:

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

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

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

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

Verwenden Sie zum Korrigieren der Logik stattdessen ein Array und überprüfen Sie den Status für jedes Element im Array.

Tippfehler? Sie haben (secondaryStatus === 'payment2' || 'payment5' || 'payment5')mit payment5zweimal wiederholt. Meinten Sie etwas anderes payment9?

Namen carStatus enthalten nicht den Status des Autos, wie es sich anhört zu enthalten; Es ist eine Funktion, die beim Aufruf den Status des Fahrzeugs zurückgibt. Es braucht auch einen verwirrend ähnlich benannten statusParameter. Nennen Sie sie, wenn überhaupt möglich, etwas anderes: vielleicht getCarStatusund was auch immer der statusParameter genauer darstellt. Vielleicht anrufen secondaryStatus: paymentType.

DRY Sie möchten den Code auch trockener machen, was gut zu der Idee passt, stattdessen Arrays zu verwenden. Sie können ein Objekt verwenden, dessen Schlüssel der erforderliche Status sind und dessen Werte die möglichen secondaryStatusWerte sowie der Rückgabewert sind, wenn der secondaryStatusgefunden wird.

Da alle Zahlungszeichenfolgen mit einer Nummer enden und sich nur diese Nummer ändert, verwenden Sie diese Nummer, um das Konfigurationsobjekt anstelle der vollständigen paymentZeichenfolgen einzurichten :

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

Live-Snippet:

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

Komponententyp Es sieht so aus, als würden Sie eine Klassenkomponente verwenden. React empfiehlt, dass Sie die Verwendung von Funktionskomponenten in neuem Code ausprobieren. Sie sagen, dass es in den meisten Fällen etwas einfacher ist, mit ihnen zu arbeiten und sie zu verstehen als klassenbasierte Komponenten, und ich stimme zu. Versuchen Sie stattdessen, funktionale Komponenten zu verwenden, falls Sie dies noch nicht getan haben.