Unterschied zwischen deklarativ und imperativ in React.js?

92

In letzter Zeit habe ich viel über die Funktionalität und die Verwendung der Facebook-JavaScript-Bibliothek React.js gelernt. Beim Sprechen seiner Unterschiede zum Rest der JavaScript Welt oft die beiden Programmierstile declarativeund imperativeerwähnt werden.

Was ist der Unterschied zwischen beiden?

Sokrates
quelle
22
latentflip.com/imperative-vs-declarative Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it.
Rickyduck
4
Tyler McGinnis schrieb einen langen Artikel darüber mit einigen guten Beispielen.
Ian Dunn
Warum lange Antwort als Kommentar hinzufügen? ..
Alex
Der obige Link ist korrekt, aber ein abschließender
James Yoo

Antworten:

159

Ein deklarativer Stil, wie er reagiert, ermöglicht es Ihnen, den Ablauf und den Status in Ihrer Anwendung zu steuern, indem Sie sagen: "Es sollte so aussehen". Ein zwingender Stil dreht das um und ermöglicht es Ihnen, Ihre Anwendung zu steuern, indem Sie sagen: "Dies ist, was Sie tun sollten".

Der Vorteil von deklarativ ist, dass Sie sich nicht in den Implementierungsdetails der Darstellung des Staates festsetzen. Sie delegieren die organisatorische Komponente, um Ihre Anwendungsansichten konsistent zu halten, sodass Sie sich nur um den Status kümmern müssen.

Stellen Sie sich vor, Sie haben einen Butler, der eine Art Metapher für ein Framework ist. Und Sie möchten Abendessen machen. In einer imperativen Welt würden Sie ihnen Schritt für Schritt sagen, wie man ein Abendessen macht. Sie müssen folgende Anweisungen geben:

Go to the kitchen
Open fridge
Remove chicken from fridge
...
Bring food to the table

In einer deklarativen Welt würden Sie einfach beschreiben, was Sie wollen

I want dinner with chicken.

Wenn Ihr Butler nicht weiß, wie man Hühnchen macht, können Sie nicht deklarativ arbeiten. Genau wie wenn Backbone nicht weiß, wie es sich selbst mutieren soll, um eine bestimmte Aufgabe zu erledigen, können Sie es nicht einfach anweisen, diese Aufgabe zu erledigen. React kann deklarativ sein, weil es zum Beispiel "weiß, wie man Hühnchen macht". Im Vergleich zu Backbone, das nur weiß, wie man sich mit der Küche verbindet.

In der Lage zu sein, den Zustand zu beschreiben, reduziert die Oberfläche für Fehler dramatisch, was ein Vorteil ist. Auf der anderen Seite haben Sie möglicherweise weniger Flexibilität bei der Vorgehensweise , da Sie die Implementierung des Status delegieren oder abstrahieren.

Nathan Hagen
quelle
74

Stellen Sie sich eine einfache UI-Komponente vor, z. B. eine Schaltfläche "Gefällt mir". Wenn Sie darauf tippen, wird es blau, wenn es zuvor grau war, und grau, wenn es zuvor blau war.

Der zwingende Weg, dies zu tun, wäre:

if( user.likes() ) {
    if( hasBlue() ) {
        removeBlue();
        addGrey();
    } else {
        removeGrey();
        addBlue();
    }
}

Grundsätzlich müssen Sie überprüfen, was aktuell auf dem Bildschirm angezeigt wird, und alle Änderungen vornehmen, die zum erneuten Zeichnen mit dem aktuellen Status erforderlich sind, einschließlich des Rückgängigmachens der Änderungen gegenüber dem vorherigen Status. Sie können sich vorstellen, wie komplex dies in einem realen Szenario sein könnte.

Im Gegensatz dazu wäre der deklarative Ansatz:

if( this.state.liked ) {
    return <blueLike />;
} else {
    return <greyLike />;
}

Da der deklarative Ansatz Bedenken trennt, muss dieser Teil nur behandeln, wie die Benutzeroberfläche in einem bestimmten Zustand aussehen soll, und ist daher viel einfacher zu verstehen.

Ahmed Eid
quelle
19

Das ist eine großartige Analogie:

* Eine zwingende Antwort : Verlassen Sie den Nordausgang des Parkplatzes und biegen Sie links ab. Fahren Sie auf der I-15 nach Süden, bis Sie zur Ausfahrt Bangerter Highway gelangen. Biegen Sie am Ausgang rechts ab, als würden Sie nach Ikea fahren. Fahren Sie geradeaus und biegen Sie an der ersten Ampel rechts ab. Fahren Sie weiter bis zur nächsten Ampel und biegen Sie dann links ab. Mein Haus ist # 298.

Eine deklarative Antwort : Meine Adresse lautet 298 West Immutable Alley, Draper Utah 84020 *

https://tylermcginnis.com/imperative-vs-declarative-programming/

serkan
quelle
15

Vergleichen Sie am besten React (deklarativ) und JQuery (imperativ), um die Unterschiede aufzuzeigen.

In React müssen Sie nur den endgültigen Status Ihrer Benutzeroberfläche in der render()Methode beschreiben, ohne sich Gedanken darüber machen zu müssen, wie Sie vom vorherigen Benutzeroberflächenstatus zum neuen Benutzeroberflächenstatus wechseln können. Z.B,

render() {
  const { price, volume } = this.state;
  const totalPrice = price * volume;

  return (
    <div>
      <Label value={price} className={price > 100 ? 'expensive' : 'cheap'} ... />
      <Label value={volume} className={volume > 1000 ? 'high' : 'low'} ... />
      <Label value={totalPrice} ... />
      ...
    </div>
  )
}

Auf der anderen Seite müssen Sie in JQuery Ihren UI-Status unbedingt ändern, z. B. die Beschriftungselemente auswählen und deren Text und CSS aktualisieren:

updatePrice(price) {
  $("#price-label").val(price);
  $("#price-label").toggleClass('expansive', price > 100);
  $("#price-label").toggleClass('cheap', price < 100);

  // also remember to update UI depending on price 
  updateTotalPrice();
  ... 
}

updateVolume(volume) {
  $("#volume-label").val(volume);
  $("#volume-label").toggleClass('high', volume > 1000);
  $("#volume-label").toggleClass('low', volume < 1000);

  // also remember to update UI depending on volume
  updateTotalPrice();
  ... 
}

updateTotalPrice() {
  const totalPrice = price * volume;
  $("#total-price-label").val(totalPrice);
  ...
}

Im realen Szenario müssen viel mehr Benutzeroberflächenelemente sowie deren Attribute (z. B. CSS-Stile und Ereignis-Listener) usw. aktualisiert werden. Wenn Sie dies unbedingt mit JQuery tun, wird dies komplex und langwierig. Es ist leicht zu vergessen, einige Teile der Benutzeroberfläche zu aktualisieren oder alte Ereignis-Listener zu entfernen (Speicherverlust) usw. Hier treten Fehler auf, dh der Benutzeroberflächenstatus und der Modellstatus sind nicht synchron.

Nicht synchronisierte Zustände werden mit dem deklarativen Ansatz von React niemals passieren, da nur der Modellstatus aktualisiert werden muss und React dafür verantwortlich ist, die Benutzeroberfläche und die Modellzustände synchron zu halten.

  • Unter dem Haken aktualisiert React alle geänderten DOM-Elemente unter Verwendung von Imperativcode.

Sie können auch meine Antwort lesen für Was ist der Unterschied zwischen deklarativer und imperativer Programmierung? .

PS: Aus dem obigen jQuery-Beispiel können Sie sich überlegen, was passiert, wenn wir alle DOM-Manipulationen in eine updateAll()Methode einfügen und sie jedes Mal aufrufen, wenn sich einer unserer Modellzustände ändert und die Benutzeroberfläche niemals nicht synchron ist. Sie haben Recht, und genau das macht React. Der einzige Unterschied besteht darin, dass jQuery updateAll()viele unnötige DOM-Manipulationen verursacht. React aktualisiert jedoch nur geänderte DOM-Elemente mithilfe seines Virtual DOM Diffing-Algorithmus .

Motorkraft
quelle
5

Imperativer Code weist JavaScript an, wie jeder Schritt ausgeführt werden soll. Mit deklarativem Code teilen wir JavaScript mit, was wir tun möchten, und lassen JavaScript die Schritte ausführen.

React ist deklarativ, da wir den gewünschten Code schreiben und React dafür verantwortlich ist, unseren deklarierten Code zu übernehmen und alle JavaScript / DOM-Schritte auszuführen, um zum gewünschten Ergebnis zu gelangen.

Nikhil
quelle
3

Eine echte Parallele in der imperativen Welt wäre, eine Bar für ein Bier zu betreten und dem Barkeeper die folgenden Anweisungen zu geben:

- Nehmen Sie ein Glas aus dem Regal

- Stellen Sie das Glas vor den Luftzug

- Ziehen Sie den Griff herunter, bis das Glas voll ist

- Gib mir das Glas.

In der deklarativen Welt würden Sie stattdessen einfach sagen: "Bier, bitte."

Der deklarative Ansatz, nach einem Bier zu fragen, setzt voraus, dass der Barkeeper weiß, wie man ein Bier serviert, und das ist ein wichtiger Aspekt der Funktionsweise der deklarativen Programmierung.

Bei der deklarativen Programmierung beschreiben Entwickler nur, was sie erreichen möchten, und es müssen nicht alle Schritte aufgelistet werden, damit dies funktioniert.

Die Tatsache, dass React einen deklarativen Ansatz bietet, macht die Verwendung einfach, und folglich ist der resultierende Code einfach, was häufig zu weniger Fehlern und mehr Wartbarkeit führt.

Da React einem deklarativen Paradigma folgt und nicht erklärt werden muss, wie mit dem DOM zu interagieren ist; Sie ERKLÄREN nur, was Sie auf dem Bildschirm sehen möchten, und React erledigt den Job für Sie.

Yilmaz
quelle
0
  • Mit Deklarativ können Sie alle Ansichten steuern. (wie als Staatsverwaltung)
  • Mit dem Imperativ können Sie die Sicht steuern. (wie als $ (this))
Naing Min Khant
quelle
0

Ich beginne mit einer Analogie: Ich habe zwei Autos, in meinen zwei Autos möchte ich, dass die Temperatur in meinem Auto eine normale Raumtemperatur von ~ 72 ° F hat. Im ersten (älteren) Auto gibt es zwei Knöpfe zur Steuerung der Temperatur (1 Knopf zur Steuerung der Temperatur und 1 Knopf zur Steuerung des Luftstroms). Wenn es zu heiß wird, muss ich den ersten Knopf einstellen, um die Temperatur zu senken und möglicherweise den Luftstrom zu ändern) und umgekehrt, wenn es zu kalt ist. Das ist zwingende Arbeit! Ich muss die Knöpfe selbst verwalten. In meinem zweiten (neueren) Auto kann ich die Temperatur einstellen / deklarieren. Das heißt, ich muss nicht an den Knöpfen herumspielen, um die Temperatur einzustellen, von der mein Auto weiß, dass ich sie auf 72 ° F deklariere / einstelle, und mein Auto wird die notwendige Arbeit leisten, um in diesen Zustand zu gelangen.

React ist dasselbe. Sie deklarieren das Markup / die Vorlage und den Status. React erledigt dann die zwingende Arbeit, um das DOM mit Ihrer App synchron zu halten.

<button onClick={activateTeleporter}>Activate Teleporter</button>

Anstatt .addEventListener()die Ereignisbehandlung einzurichten, deklarieren wir, was wir wollen. Wenn Sie auf die Schaltfläche klicken, wird die activateTeleporterFunktion ausgeführt.

Ryan Efendy
quelle