Ich habe gelernt, wie man in einer Woche produktiv mit React wird, und das können Sie auch.

Avatar of Sarah Drasner
Sarah Drasner am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Dieser Artikel richtet sich nicht an erfahrene React-Profis, sondern an diejenigen von uns, die beruflich Webseiten erstellen und neugierig sind, wie React uns helfen kann, über die Aktualisierung von Benutzeroberflächen nachzudenken. Ich war schon seit einiger Zeit von React fasziniert, und da es nun einen gewissen Stellenwert in der Community sowie gute Bewertungen erlangt hat, schien der Zeitpunkt zum Lernen gerechtfertigt. Es gibt ständig so viele neue Technologien in der Frontend-Entwicklung, dass es manchmal schwer zu wissen ist, ob sich die Mühe, etwas Neues zu lernen, auszahlt. In diesem Artikel werde ich darlegen, was meiner Meinung nach die wertvollsten praktischen Erkenntnisse sind, damit Sie loslegen können.

Faire Warnung

Ich habe nur etwa eine Woche mit diesem Material gearbeitet. Das ist Absicht. Ich schreibe dies, während ich noch frisch mit der Technologie bin und darüber aus dieser Perspektive schreiben kann. In diesem Zustand kann ich mich viel besser an die Stolpersteine und Erkenntnisse erinnern, die mir auf dem Weg begegnet sind.

Ich habe den Kurs von Wes Bos, React for Beginners, sowie React.js Introduction For People Who Know Just Enough jQuery To Get By genutzt. Ich kann diese Ressourcen nicht genug empfehlen.

In zwei Tagen habe ich das gemacht

Siehe den Pen Baby’s First React Attempt von Sarah Drasner (@sdras) auf CodePen.

Es ist nicht perfekt, aber es geht weit über das hinaus, was ich in dieser Zeit allein hätte erreichen können.

Wenn Sie zu den Leuten gehören, die sich direkt hineinstürzen und alles lernen möchten, einschließlich des Builds und des erforderlichen Toolings, dann ist das großartig! Hier können Sie beginnen. Ich würde auch diesen ziemlich guten Frontend Masters Kurs empfehlen: Modern Web Apps.

Mythbusters: Ausgabe Praktikabilität in React

Bevor wir beginnen, möchte ich ein paar wichtige Mythen entkräften, die meiner Meinung nach für viele Leute hinderlich sind.

Myth #1: Sie müssen Inline-Styles verwenden, um React zu nutzen.

Nein! Überhaupt nicht. Sie können CSS wie gewohnt verwenden. Nachdem ich viel Zeit mit der Refaktorierung einer riesigen CSS-Codebasis verbracht habe, würde ich sagen, dass dies ziemlich wichtig ist. React, da es ziemlich neu ist, hat sich noch nicht dem Test von Design-Updates gestellt, wie es andere Technologien getan haben. Wenn ich Tausende von Zeilen mit Inline-Styles durchgehen müsste, nur um Dinge wie padding und line-height zu aktualisieren, wäre ich ein trauriger Entwickler.

Das gesagt, es gibt Zeiten, in denen Inline-Styles Sinn machen. Wenn Sie eine Komponente haben, die ihre Stile je nach Zustand ändert (z. B. eine Datenvisualisierung), wäre es sinnvoll, mit Inline-Styles zu arbeiten, damit Sie keine unpraktische Anzahl statischer Stile (an mehreren Stellen) pflegen müssen, um alle möglichen Zustände abzudecken.

Ich würde jedoch denken, dass dies zusätzlich zu einem Basis-CSS liegt, das die Anwendung verwendet, und eher eine Ausnahme als eine Regel darstellt. Die Web ist ein großer Ort, daher gibt es keine Absolutheit.

Myth #2: Sie müssen JavaScript-Syntax für Elementattribute verwenden, was überhaupt nicht wie HTML ist.

Eines der Dinge, die ich am Lehrstil von Wes Bos wirklich liebe, ist, dass er den Zuschauer zum vertrauteren Ansatz und zur vertrauteren Implementierung führt. Ich neige generell dazu, auf der Seite des einfachen, weniger verschleierten Codes zu bleiben, obwohl ich verstehe, dass andere höhere Abstraktionsebenen bevorzugen.

Er schlägt vor, unser Markup mit JSX zu schreiben, was unserem Freund, dem traditionellen HTML, ähnlicher ist, daher fand ich es viel klarer. Anstatt also dies

return React.createElement("p", {className: "foo"}, "Hello, world!");

Würden wir das schreiben

return (<p className="foo">Hello, world!</p>);

Beides funktioniert. Aber wenn unsere Markup immer komplexer wird, habe ich festgestellt, dass die Vertrautheit von HTML in Form von JSX meinem Verständnis diente. Bitte bedenken Sie jedoch, dass es auch mit JSX geringfügige Unterschiede gibt.

Myth #3: Um React auszuprobieren, müssen Sie alle Build-Tools verstehen.

Es stimmt zwar, dass Sie zum Verwenden von React Build-Tools verwenden müssen, weshalb Tutorials normalerweise damit beginnen. Ich würde jedoch empfehlen, dass Sie sich als absoluter Anfänger auf CodePen austoben. Es ist eine gute Möglichkeit, schnell zu iterieren und zu lernen, bevor Sie viel Zeit in eine brandneue Technologie investieren.

React in typischen Anwendungen verwenden

In typischen Anwendungen, die React 1.14+ verwenden, würden wir damit beginnen, React und ReactDOM anzufordern

var React = require('react');
var ReactDOM = require('react-dom');

Und dann ReactDOM.render aufrufen

ReactDOM.render(routes, document.querySelector('#main'));

React in CodePen verwenden

In unserem Fall wählen wir einfach React aus dem Dropdown-Menü im JS-Panel (klicken Sie auf das Zahnradsymbol oben im Panel) und verwenden dann Babel als Compiler.

Wir müssen React oder React DOM nicht requiren, da wir nichts geroutet haben und die App-Komponente direkt verwenden. Unser Code wird einfach geändert zu

React.render(<App/>, document.querySelector("#main"));
<div id="main"></div>

Außerdem benötigen Sie zum Starten die React Devtools-Erweiterung für Chrome oder die React Devtools-Erweiterung für Firefox, die hervorragend zum Debuggen unseres virtuellen DOMs geeignet ist.

Wenn Sie CodePen verwenden, können Sie die Debug View verwenden, und sie findet React richtig

Einsatzbereit

Die grundlegenden Bausteine, die Sie kennen müssen, um etwas zu erstellen, sind wie folgt:

// App
var App = React.createClass({
  render: function() {
    return (
      <div className="foo">Hello, world!</div>
    )
  }
});
 
ReactDOM.render(<App/>, document.querySelector("#main"));

Siehe den Pen Hello World React von Sarah Drasner (@sdras) auf CodePen.

Lassen Sie uns das aufschlüsseln. In der letzten Zeile finden wir die main div-ID, und darauf rendern wir die <App />-Komponente, die unsere gesamte React-Anwendung lädt. Sie können Ihren React-Tab in Devtools verwenden, um nun das erstellte DOM-Element zu sehen.

Wir haben <App /> als erste Komponente angehängt. Das Erste, was hier zu beachten ist, ist, dass dieses Tag großgeschrieben ist – obwohl dies nicht zwingend erforderlich ist, ist es eine bewährte Methode bei React-Komponenten. Das Zweite ist, dass es selbstschließend ist. Tags in React müssen geschlossen werden, entweder durch ein zusätzliches schließendes Tag (z. B. </div>) oder ein selbstschließendes Tag (z. B. <hr> würde zu <hr /> werden). Das ist einfach die Funktionsweise von JSX, andernfalls wird ein Fehler ausgelöst.

Beachten Sie die Struktur zur Erstellung der App-Komponente oben. Sie werden sich sehr an diese Syntax gewöhnen, da alles, was wir heute bauen werden, auf diesem Schlüsselbaustein basiert.

Das Letzte, was zu beachten ist, ist, dass wir anstelle von class className auf dem Element verwenden. Dies ist ein Stolperstein, wenn Sie daran gewöhnt sind, HTML-Markup für eine Webseite zu schreiben. Glücklicherweise ist es leicht zu lösen. Weitere Informationen zu JSX und seiner Syntax finden Sie in diesen Dokumenten, die wirklich gute Ressourcen sind.

// App
var App = React.createClass({
  render: function() {
    return (
      <Header />
    )
  }
});
 
// Header
var Header = React.createClass({
 render: function() {
   return (
     <div className="foo">Hello, world!</div>
   )
 }
});
 
ReactDOM.render(<App/>, document.querySelector("#main"));

Siehe den Pen Hello World React von Sarah Drasner (@sdras) auf CodePen.

Im nächsten Schritt erweitern wir die App mit einer Komponente. Header kann beliebig benannt werden, zur Klarheit haben wir ihn nach seiner Rolle im Dokument benannt. Sie können sehen, dass wir, wenn wir auch ein Navigationselement hinzufügen wollten, dies ziemlich einfach tun könnten. Hier ist die gleiche Seite mit einer Standard-Bootstrap-Reihe von Schaltflächen für eine <Nav />-Komponente und der semantischeren h1 für unser „Hello, World!“ anstelle eines div

// App
var App = React.createClass({
render: function() {
 return (
   <div>
     <Nav />
     <Header />
   </div>
  )
 }
});
 
// Nav
var Nav = React.createClass({
 render: function() {
   return (
    <ul className="nav nav-pills">
      <li role="presentation" className="active">Home</li>
      <li role="presentation">Profile</li>
      <li role="presentation">Messages</li>
    </ul>
  )
 }
});
 
// Header
var Header = React.createClass({
 render: function() {
   return (
     <h1 className="foo">Hello, world!</h1>
   )
 }
});
 
ReactDOM.render(<App/>, document.querySelector("#main"));

Siehe den Pen Hello World React von Sarah Drasner (@sdras) auf CodePen.

Ziemlich einfach, oder? Es ist wie die Bausteine jeder Webseite. Wir erstellen die Navigation und den Header und wenden diese Komponenten auf die App-Komponente an, die im Body gerendert wird. Der einzige wirkliche Stolperstein des letzten Beispiels wäre das seltsame zusätzliche Div, das Sie um <Header /> und <Nav /> sehen. Das liegt daran, dass wir immer ein einziges Element zurückgeben müssen. Wir können keine zwei Geschwisterelemente haben, also packen wir sie in ein einziges Div.

Nachdem Sie nun die Bausteine verstehen, können Sie wahrscheinlich ziemlich einfach eine Seite mit React und React-Komponenten zusammenstellen. Ich würde vorschlagen, ein Seitenlayout zu refaktorieren, das Sie bereits erstellt haben, nur um zu lernen. Werfen Sie das Stylesheet hinein und fügen Sie die restlichen Teile Stück für Stück zusammen, bis Sie das Gerüst rekonstruiert haben. Es ist eine großartige Übung.

Es gibt eine Möglichkeit, diesen Prozess zu automatisieren, aber ich würde nicht empfehlen, ein solches Tool zu verwenden, bis Sie die Schritte des Erstellens von Dingen selbst bereits durchlaufen haben. Auf diese Weise wissen Sie, was vor sich geht, wenn Sie später auf Probleme stoßen.

Die üblichen Verdächtigen: Variablen & Event-Handling

Lassen Sie uns etwas einfaches Event-Handling machen und zuerst ein paar einfache Variablen einfügen, nur um zu sehen, wie das funktioniert.

Betrachten Sie die erste Demo noch einmal (wir werden diese im gesamten Artikel verwenden)

Siehe den Pen Baby’s First React Attempt von Sarah Drasner (@sdras) auf CodePen.

Die Blog-Post-Komponente hat ein ziemlich einfaches Markup, also fangen wir damit an

// Blog Post
var Post = React.createClass({
  render : function() {
    return (
      <div className="blog-post">
        <h3 className="ptitle">{this.props.ptitle}<small>{this.props.date}</small></h3>
        <img className="thumbnail" src={this.props.pimg} />
        <p>{this.props.postbody}</p>
        <div className="callout callout-post">
          <ul className="menu simple">
          <li>Author: {this.props.author}</li>
          <li>Comments: {this.props.comments}</li>
          <li>Tags: {h.getTaggedName()}</li>
          </ul>
        </div>
      </div>
    )
  }
});

Fügen wir eine beliebige Variable und einen Event-Handler hinzu, um zu sehen, wie das funktioniert. Das Erste, woran man denken muss, ist, dass geschweifte Klammern React mitteilen, dass wir bereit sind, JavaScript zu verwenden, wenn wir JSX verwenden. Daher wird unsere Variable so aussehen: {var}.

Wir fügen die Variablendeklaration innerhalb des render-Funktionsaufrufs ein, aber bevor wir das Markup zurückgeben. Wir können dann darauf zugreifen, indem wir die Variable aufrufen, in diesem Fall {com}. Das Klickereignis ist ein Inline-onClick-Handler, der wahrscheinlich gegen die Best Practices verstößt, an die Sie gewöhnt sind. Dies ist ein Name, den wir gewählt haben, während render eine Framework-Methode ist. Wir rufen {this.tryClick} auf und schreiben eine Methode namens tryClick (ein beliebiger Name) innerhalb derselben Komponente, wie folgt:

// Blog Post
var Post = React.createClass({
  tryClick : function() {
    alert('just trying out click events lalala');
  },
  render : function() {
    var com = "Comments";
    return (
      <div className="blog-post">
        <h3 className="ptitle">{this.props.ptitle}<small>{this.props.date}</small></h3>
        <img className="thumbnail" src={this.props.pimg} />
        <p>{this.props.postbody}</p>
        <div className="callout callout-post">
          <ul className="menu simple">
          <li>Author: {this.props.author}</li>
          <li>{com}: {this.props.comments}</li>
          <li>Tags: {h.getTaggedName()}</li>
          </ul>
        </div>
      </div>
    )
  }
});

Die Syntax für Ereignisse in React beginnt mit „on“ und ist camel-cased. Zum Beispiel

  • click = onClick
  • mouseEnter = onMouseEnter
  • keyPress = onKeyPress

Sie finden eine vollständige Liste aller unterstützten Ereignisse.

Kombination von React und anderen Bibliotheken (hier: Greensock)

Ich liebe GSAP für Animationen. Sie können andere Bibliotheken innerhalb von React verwenden, also kombinieren wir GSAP und React und sehen, wie das funktioniert.

Wir wollen auf andere Bibliotheken zur richtigen Zeit zugreifen, also müssen wir sicherstellen, dass sie unmittelbar nach der ersten Render-Methode aufgerufen werden. Die Methode, die wir dafür verwenden, heißt componentDidMount. Wir werden weiter unten etwas mehr über andere Lifecycle-Methoden erklären, aber was Sie im Moment wissen müssen, ist, dass diese Methode unmittelbar nach dem Einfügen der Komponente in das Dokument aufgerufen wird.

Wenn Sie jQuery gewohnt sind, sind Sie es gewohnt, Elemente direkt aus dem DOM zu greifen. In diesem Fall verwenden wir, obwohl wir DOM-Elemente tweaken, Reacts getDOMNode() anstelle des direkten Zugriffs. Sie werden auch sehen, dass wir die Funktion zum Tween tatsächlich in der App-Komponente aufrufen und sie einfach an unsere Boxen weitergeben. (Möglicherweise müssen Sie auf "wiederholen" klicken, um die Animation zu sehen.)

Siehe den Pen 794b375a8725b039483c83fb63a4bd5a von Sarah Drasner (@sdras) auf CodePen.

// App
var App = React.createClass({
 componentDidMount: function() {
    var sq1 = this.refs.first.getDOMNode();
    var sq2 = this.refs.second.getDOMNode();
    var sq3 = this.refs.third.getDOMNode();
    var sq4 = this.refs.fourth.getDOMNode();
    var sq5 = this.refs.fifth.getDOMNode();
    var allSq = [sq1, sq2, sq3, sq4, sq5];
   
    TweenLite.set(allSq, {css:{transformPerspective:400, perspective:400, transformStyle:"preserve-3d"}}); 

    TweenMax.to(sq1, 2.5, {css:{rotationX:230, z:-600}, ease:Power2.easeOut}, "+=0.2");
    TweenMax.to(sq2, 2.5, {css:{rotationY:230, z:-150}, ease:Power4.easeOut}, "+=0.2");
    TweenMax.to(sq3, 2.5, {css:{rotationX:500, z:150}, ease:Power2.easeInOut}, "+=0.2");
    TweenMax.to(sq4, 2.5, {css:{rotationY:500, z:-150}, ease:Power4.easeOut}, "+=0.2");
    TweenMax.to(sq5, 2.5, {css:{rotationX:1000, z:100}, ease:Power2.easeOut}, "+=0.2");
 },
 render: function() {
   return (
     <div className="scene">
        <Box ref="first"></Box>
        <Box ref="second"></Box>
        <Box ref="third"></Box>
        <Box ref="fourth"></Box>
        <Box ref="fifth"></Box>
    </div>
   )
 }
});

// Box
var Box = React.createClass({
  render: function() {
    return (
      <div className="squares"></div>
    )
  }
});
 
ReactDOM.render(<App/>, document.querySelector("#main"));

Sie sind es vielleicht gewohnt, über jQuery oder Vanilla JavaScript auf das DOM zuzugreifen. Wir können dies immer noch tun, aber hier greifen wir über getDOMNode() und refs auf DOM-Teile zu, in dieser Zeile: var sq1 = this.refs.squares1.getDOMNode();. Sie können hier etwas mehr darüber lesen: React docs.

Es gibt spezifischere React-Methoden, um Bewegung in Ihre Projekte einzubinden – eine wirklich großartige ist Cheng Lous React-Motion und eine weitere gute Erwähnung ist React-GSAP-Enhancer.

Erstellen einer globalen Hilfsfunktion

Sie können sogar Hilfsfunktionen schreiben, auf die mehrere Komponenten leicht zugreifen können. Wir würden diese mit der gleichen Punktnotation verwenden, die wir mit this.functionName verwendet haben. Wir speichern die Hilfsfunktion (in diesem CodePen-Demo tun wir dies am Anfang der Datei, in realen Anwendungen werden sie jedoch in einer separaten Datei gespeichert) und deklarieren jede Funktion als Objekt, genauso wie Sie es innerhalb der Komponentenstruktur tun.

So etwas wie das korrekt formatierte Datum in der ersten Demo mit den Blogbeiträgen wäre

var h =  {
  getTime: function() {
     var month = ["jan", "feb", "march"]; // …. and so on
     var d = new Date();
     var mon = month[d.getMonth()];
     var day = d.getDate();
     var year = d.getFullYear();
     var dateAll = mon + " " + day + ", " + year;
   
     return dateAll;
  }
};

Und wird so verwendet: {h.getTime()}

Das Gute: State Management

Ok! Nachdem wir die Grundlagen geklärt haben, kommen wir zu einigen der coolen Sachen.

React ist sicherlich gut darin, Apps mit leicht verständlichen, kleinen Komponenten zu erstellen, aber es ist besonders gut darin, den Zustand (State) für diese Komponenten zu verwalten. Tauchen wir ein wenig tiefer ein.

Für diesen Teil werden wir zwei wichtige Aspekte des Zugriffs auf und der Arbeit mit sich ändernden Dingen besprechen.

  1. Das erste ist state. Die Komponente selbst besitzt ihn, was bedeutet, dass er auf die Komponente beschränkt ist und wir ihn so referenzieren: {this.state.foo}. Wir können den state durch Aufruf von this.setState() aktualisieren.
  2. Das zweite bezieht sich darauf, wie wir schreibgeschützte Daten vom Elternteil an die Komponente weitergeben (denken Sie daran, dass app der Elternteil von header im ersten Beispiel ist). Wir bezeichnen dies als props, also als Eigenschaft, und verwenden sie direkt in den Komponenten mit {this.props.foo}. Diese Daten können von ihren Kindern nicht geändert werden.

Jedes Mal, wenn wir eines dieser beiden Dinge ändern und unsere Komponente davon abhängt, wird React die Teile Ihrer Komponente, die es benötigt, neu rendern.

Die Schönheit des virtuellen DOM ist, dass React nur herausfindet, welche DOM-Knoten aktualisiert werden müssen.

Ich habe viel über State gelesen, aber ich glaube, Wes hat es am klarsten formuliert, also werde ich ihn paraphrasieren: Wenn Sie jQuery gewohnt sind, speichern Sie alle Ihre Daten im DOM. React vermeidet dies gänzlich, indem es die Daten in einem Objekt (State) speichert und dann Dinge basierend auf dem Objekt rendert. Es ist wie ein großes Master-Objekt, auf dem alles basiert.

Props ausprobieren

Probieren wir zuerst this.props aus. Wir fügen {this.props.title} zur Header-Komponente hinzu und können dann über die App darauf zugreifen. Wir fügen einen String hinzu, um den Titel zu erstellen

// App
var App = React.createClass({
  render: function() {
    return (
      <Header greeting="Hello, world!" />
    )
  }
});
 
// Header
var Header = React.createClass({
  render: function() {
    return (
      <div className="foo">
        <h1>{this.props.greeting}</h1>
      </div>
    )
  }
});
 
ReactDOM.render(<App/>, document.querySelector("#main"));

Wir können auch einen Standardwert für Props in der passend benannten getDefaultProps-Lifecycle-Methode hinzufügen. Das ist großartig, weil man manchmal nicht für jede Komponente Props angeben muss. Ein Beispiel dafür wäre ein Standard-Profil-Avatar, wenn der Benutzer noch keinen festgelegt hat, wie das Ei bei Twitter, oder das Setzen einer Liste als leeres Array, das später gefüllt wird.

var ProfilePic = React.createClass({
  getDefaultProps: function() {
    return {
      value: 'twitter-egg.jpg'
    };
   ...
});

Sachen machen

Lassen Sie uns nun darauf aufbauen, um ein wenig mit State zu arbeiten. Wenn wir this.state schließlich ändern wollen, müssen wir ihn vorbereiten. Dazu verwenden wir getInitialState, was uns erlaubt, zu definieren, was der State von Anfang an ist. Ohne dies können wir keinen State hinzufügen.

Ändern wir einfach den Hintergrund basierend auf der Benutzerauswahl.

Siehe den Pen 928579628fd2ecb0f98aff9c08774e93 von Sarah Drasner (@sdras) auf CodePen.

// App
var App = React.createClass({
  /*setting state*/
  getInitialState: function() {
    return {
      bgColor: "teal"
    };
  },
  /*changes state*/
  handleColorChange: function (color) {
    // when we set state directly, react doesn't know
    // about it. that's why we use setState
    this.setState({ bgColor: color });
  },
  /*for the lifecycle methods*/
  updateBackgroundColor: function () {
    var body = document.querySelector('body')
    body.style.background = this.state.bgColor
  },
  /*lifecycle methods*/
  componentDidMount: function () { 
    this.updateBackgroundColor()
  },
  componentDidUpdate: function () { 
    this.updateBackgroundColor()
  },
  render: function() {
    return (
    /* by calling the title here on the component, we can access this.props on header */
      <div className="foo">
        <h1>Hello, World!</h1>
        <label>What color?
          <ColorPicker value={this.state.bgColor} onColorChange={this.handleColorChange}/>
        </label>
      </div>
    )
  }
});

// ColorPicker component
var ColorPicker = React.createClass({
  propTypes: {
    value: React.PropTypes.string.isRequired,
    onColorChange: React.PropTypes.func
  },
  handleChange: function(e) {
    e.preventDefault();
    var color = e.target.value
    
    // If whoever rendered us (the ColorPicker) is interested
    // when the color changes, let them know
    if (this.props.onColorChange)
      this.props.onColorChange(color);
  },
  render: function() {
    return (
      <select value={this.props.value} onChange={this.handleChange}>
        <option value="orangered">orangered</option>
        <option value="teal">teal</option>
        <option value="orange">orange</option>
        <option value="indigo">indigo</option>
        <option value="red">red</option>
      </select>
    )
  }
});

ReactDOM.render(<App/>, document.querySelector('#main'));

Ein wichtiger Teil davon ist zu bedenken, dass wir die handleChange-Funktion benötigen.

Im normalen DOM-Leben würden native Auswahlen nicht erfordern, dass Sie so etwas tun, da sie sich automatisch an die Auswahl des Benutzers anpassen würden. In React wird der gesamte State von der Komponente verwaltet. Wenn Sie also möchten, dass ein Eingabefeld oder eine Auswahl auf Änderungen reagiert, müssen Sie dies selbst schreiben. Das bedeutet, dass die Komponente für den State verantwortlich ist, nicht der Benutzer.

Das mag nach viel Arbeit für wenig Ertrag aussehen, aber wir haben diese Beispiele bewusst schlank gehalten. Die coolen Teile von React kommen wirklich zum Tragen, wenn Sie mit viel Komplexität umgehen. So sehr ich jQuery liebe (und ich liebe jQuery immer noch, es ist keine boolesche Variable), Sie müssen ziemlich häufig Überprüfungen durchführen, wenn sich etwas ändert. React löst dies, indem es diese Notwendigkeit aufgrund der Einfachheit des Datenflusses beseitigt, was es auch in hochkomplexen Anwendungen leichter verständlich macht.

State-Konzepte

Nachdem wir nun die absoluten Grundlagen beherrschen, werfen wir einen schnellen Blick darauf, warum wir das tun, was wir tun, sowie auf einige Best Practices.

React funktioniert am besten, wenn wir States aktualisieren und untergeordnete Komponenten neu rendern. Grundsätzlich möchten wir, dass diese Komponenten größtenteils zustandslos sind und Daten von übergeordneten Komponenten erhalten. Die Komponenten an der Spitze unserer Hierarchie, wie unsere App, funktionieren am besten, wenn sie größtenteils zustandsbehaftet sind. Auf diese Weise verwalten sie den Großteil der Interaktionslogik und übergeben den State mithilfe von Props. Dennoch wird es Zeiten geben, in denen jede Komponente ihren eigenen State hat. Es ist jedoch wichtig zu bedenken, dass Geschwister nicht direkt miteinander sprechen sollten, sondern mit ihrer Elternkomponente.

Daher möchten wir den State so weit wie möglich in der Komponente behalten. Sie müssen sich nie wirklich darum kümmern, *wann* etwas gerendert wird. Alles, worum Sie sich kümmern müssen, ist, wann sich der State ändert, und React kümmert sich um das Rendering für Sie.

Diese Art von Best Practice führt direkt dazu, warum ich Ihnen auch davon abrate, Props in getInitialState zu verwenden, und hier gibt es weitere Informationen darüber, warum dies als Antipattern gilt.

Wir sollten State nicht überstrapazieren. Das Rendern der Komponenten ist ziemlich schnell, aber die Leistung kann sinken, wenn Sie versuchen, zu viel State zu verwalten. Es gibt einige Möglichkeiten, dies zu umgehen, sobald es tatsächlich ein Problem ist, aber am besten ist es, gar nicht erst in diese Lage zu geraten.

Der Rest dieses Artikels befasst sich damit, wie man diese States am besten verwaltet und die unveränderlichen Bedenken in der oberen Hierarchie belässt, während man sich immer noch auf unsere zustandslosen Komponenten weiter unten bezieht.

Referenzen

Wir können auch auf Informationen über das Element mit etwas namens ref zugreifen. Wir verwenden Refs, indem wir sie an jede Komponente anhängen. Sie wird dann während der render()-Methode zurückgegeben, und wir können uns dann außerhalb der render()-Methode darauf beziehen. Das ist unglaublich nützlich.

Betrachten wir noch einmal den ersten Pen. Denken wir einen Moment darüber nach, wie wir diese neuen Blogbeiträge erstellen, und nutzen wir dabei Refs.

In jedem Formulareingabefeld haben wir eine Referenz, wie z.B.

<input type="text" ref="name" placeholder="Full Name required" required />

Am Formularelement selbst rufen wir

onSubmit={this.createPost}

auf, was sich auf die Funktion createPost oberhalb der Render-Funktion bezieht und Refs verwendet, um Informationen aus dieser Einreichung zu speichern.

var post = {
 name : this.refs.name.value,
 ...
}

und dann haben wir eine Möglichkeit, darauf im App-Status mit this.props zu verweisen.

this.props.addPost(post);
refs-overview

Das ist ziemlich praktisch, denn jetzt haben wir eine Variable `post`, die Objekte mit Informationen über ihren Namen (hier gezeigt), Datum, Details usw. speichert. Wir haben das alles noch nicht im App-Status gespeichert, sondern nur einen Weg dafür geschaffen, dass die App es verwenden kann. Das behandeln wir als Nächstes, zusammen mit keys.

Ich habe dieses Beispiel verwendet, um über Refs im Allgemeinen zu sprechen, aber in realen Anwendungen sollten Sie vielleicht etwas wie form-serialize in Betracht ziehen, um Formularfelder für die Übermittlung über AJAX zu serialisieren.

Keys und Verwendung von Refs

In unserem letzten Abschnitt haben wir eine Möglichkeit geschaffen, die gesammelten Daten aus dem Formular zu speichern, ohne sie weiterzugeben. Das liegt daran, dass wir in React diesen Zustand auf der obersten Ebene unserer Hierarchie verwalten wollen. Um diesen Zustand zu speichern, initialisieren wir unseren anfänglichen Zustand mit einem leeren Objekt. Dort werden wir letztendlich unsere Post-Daten speichern.

getInitialState : function() {
  return {
    posts: {}
  }
},

Dann haben wir unsere `addPost`-Funktion. Beachten Sie, dass wir diese hier statt im Formular verwalten, obwohl wir sie vom Formular aus aufgerufen haben. Wir geben dem Zustand einen Zeitstempel, um die Beiträge eindeutig zu halten, und setzen auch den Zustand für die Beiträge.

addPost: function(post) {
  var timestamp = (new Date()).getTime();
  // update the state object
  this.state.posts['post-' + timestamp] = post;
  // set the state
  this.setState({ posts : this.state.posts });
},

Jedes Kind in einem Array sollte einen eindeutigen key.prop haben. Dies ist wichtig, da React so viel wie möglich vom vorhandenen DOM wiederverwenden wird. React verwendet keys, um zu verfolgen, welche Elemente im DOM es aktualisieren soll. Das erspart uns das Neuzeichnen aller DOM-Elemente, wenn wir neu rendern. Das hilft der Leistung unserer App.

Schauen wir uns jetzt noch einmal die App an und sehen wir, was wir mit unseren neu gespeicherten Daten aus dem Formular machen.

// App
var App = React.createClass({
  getInitialState : function() {
    return {
      posts : {}
    }
  }, 
  addPost : function(post) {
    var timestamp = (new Date()).getTime();
    // update the state object
    this.state.posts['post-' + timestamp] = post;
    // set the state
    this.setState({ posts : this.state.posts });
  },
  renderPost : function(key){
    return <NewPost key={key} index={key} details={this.state.posts[key]} />
  },
  render : function() {
   ...
    return (
      <div>
        <Banner />
	    ...
          <div className="list-of-posts">
              {Object.keys(this.state.posts).map(this.renderPost)}
          </div>
          <Submissions addPost={this.addPost}/>
        </div>
      </div>
    )
  }
});

Sie sehen, dass wir beim Rendern der App `Object.keys` verwenden, um ein neues Array zu erstellen. Dann verwenden wir .map() mit der zuvor erstellten Funktion `renderPost`. Für diejenigen, die mit .map() nicht vertraut sind: Es ist nützlich, um ein Array aus einem vorhandenen zu erstellen, man kann es sich wie eine Schleife vorstellen.

<div className="list-of-posts">
  {Object.keys(this.state.posts).map(this.renderPost)}
</div>

Lassen Sie uns nun die `renderPost`-Funktion erstellen, die wir gerade aufgerufen haben. Wir übergeben den Schlüssel als Parameter und weisen ihn als Schlüssel zu, den Index, und erstellen ein Objekt, das wir `details` nennen, um Informationen über den Zustand der Beiträge zu speichern.

renderPost: function(key) {
  return <NewPost key={key} index={key} details={this.state.posts[key]} />
},

Es mag seltsam erscheinen, dass wir einen key und einen index übergeben, aber innerhalb einer Komponente können wir die Schlüssel-prop nicht aufrufen, daher übergeben wir eine andere namens index. Diese `renderPost`-Funktion erstellt einfach eine <NewPost />-Komponente für jedes Element in unserem Array, mit übergebenen Details, auf die wir zugreifen können. Das ist ziemlich genial, denn das bedeutet, dass, wenn sich etwas in unserem Zustand ändert, es sich nach unten ausbreitet und wir es an einer Stelle verwalten können.

Hier ist die <NewPost />-Komponente, in der wir die von der App übergebenen Details verwenden, um alle Informationen zu rendern. Sie sehen, dass die zuvor erstellte Hilfsfunktion für das korrekt formatierte Datum hier als {h.getTime()} verwendet wird.

/*
  NewPost
  <NewPost />
*/
var NewPost = React.createClass({
  render : function() {
    var details = this.props.details;
    return (
      <div className="blog-post">
        <h3 className="ptitle">{details.title}<small>{h.getTime()}</small></h3>
        <img className="thumbnail" src={details.image} alt={details.name}/>
        <p>{details.desc}</p>
        <div className="callout callout-post">
          <ul className="menu simple">
          <li>Author: {details.name}</li>
          <li>Comments: 0</li>
          <li>Tags: {h.getFunName()}</li>
          </ul>
        </div>
      </div>
    )
  }
});
Keys Overview

Siehe den Pen Baby’s First React Attempt von Sarah Drasner (@sdras) auf CodePen.

Alles zusammen jetzt

Jetzt, wo wir Keys verstehen, schauen wir uns die große Zusammenfassung an. Wir haben getInitialState, componentDidMount und render besprochen, aber es gibt noch eine weitere Montagemethode für React. Sie heißt componentWillMount. Sie ähnelt componentDidMount, wird aber sofort ausgeführt, *bevor* die Komponente zum ersten Mal gerendert wird.

Dieses Diagramm enthält nicht alles, was in React verfügbar ist, sondern nur einen Einblick in das, was wir bisher behandelt haben und genug, um Ihnen den Einstieg zu ermöglichen.

Fazit

Es gibt viel mehr zu lernen als in diesem Artikel über React, dies ist nur der Anfang. Hoffentlich gibt diese Anfängerreise anderen einen kleinen Einblick, wie man loslegt. Dieser Beitrag war 20 Seiten lang und wir sind noch nicht einmal auf eine Menge anderer wichtiger und verwandter Themen eingegangen, darunter unter anderem ES6, Browserify, Gulp, Webpack oder eine Vielzahl alternativer Implementierungen.

Für weiteres Lernen empfehle ich nochmals *dringend*, sich in Wes Bos' Kurs zu vertiefen. Er bietet einen Rabatt von 10 % für CSS-Tricks-Leser mit dem Code CSSTRICKS, sowie Videos auf Frontend Masters. Michael Jackson hat einen wunderbaren Schulungskurs, für den Sie sich anmelden können (er kommt im März nach Trulia in San Francisco! Bleiben Sie dran für Anmeldungen). Es gibt auch ein großartiges Buch von Artemij Fedosejev namens React Essentials und diese Liste, die es wert ist, von Artem Sapegin als Lesezeichen markiert zu werden. Es sollte nicht unterschätzt werden, dass die React Docs ziemlich gute Ressourcen sind. Viel Spaß beim Lernen!

Vielen Dank an Michael Jackson, Wes Bos und Val Head für das Korrekturlesen dieses Artikels.