Du hast deinen AdBlocker an?

Es wäre ein Traum, wenn du ihn für t3n.de deaktivierst. Wir zeigen dir gerne, wie das geht. Und natürlich erklären wir dir auch, warum uns das so wichtig ist. Digitales High-five, deine t3n-Redaktion

t3n 41

Die JavaScript-Punks: Was die JS-Bibliothek React anders macht

    Die JavaScript-Punks: Was die JS-Bibliothek React anders macht

Facebooks JavaScript-Bibliothek React bricht zwar mit gewohnten Konventionen – bietet dafür aber ziemlich leistungsfähige Anwendungen. Mit dem Framework React Native lassen sich diese zudem in native Mobile-Apps umwandeln. Wie der Einstieg in die Arbeit mit React gelingt, zeigt die Beispiel-Applikation in diesem Artikel.

Spätestens seit das Framework React Native Ende März 2015 erschienen ist, ist React in aller Munde. Dabei handelt es sich um eine leistungsstarke JavaScript-Bibliothek, die der Entwickler Jordan Walke als persönliches Projekt bei Facebook realisierte. 2013 lösten er und sein Team React aus der Facebook-spezifischen Umgebung, überführten die Bibliothek für den Einsatz bei Instagram in eine eigenständig lauffähige Umgebung und veröffentlichten sie als Open Source.

Zunächst nahm die JavaScript-Community React aufgrund der darin umgesetzten Ideen durchaus gemischt auf. Doch dann holte React im Rennen der JavaScript-Bibliotheken zunehmend auf und ist heute beim Einsatz für Websites wie Facebook, Instagram, AirBnB oder Feedly ebenso beliebt wie in Githubs Open-Source-Editor Atom.

Oftmals wird React mit populären JavaScript-Frameworks wie Angular, Backbone oder Ember verglichen. Doch dabei handelt es sich um Web-Application-Frameworks, die ein ganzheitliches Werkzeug für die Erstellung von Anwendungen im Browser sein wollen. React hingegen will höchstens das „V“ – also der „View“ – in MVC (Model – View – Controller) sein und arbeitet mit beliebigen anderen Frameworks oder Bibliotheken zusammen.

Die mit React erstellten Komponenten sind View-Templates mit Event-Handler und eigener Zustandsverwaltung, die zusätzlich ihr benötigtes HTML und CSS enthalten können. Damit haben sie außer React selbst keine weiteren Abhängigkeiten und lassen sich universell sowie gemeinsam mit anderen JavaScript-Umgebungen und -Frameworks einsetzen. Zwar sind einzelne Elemente von Frameworks wie Angulars „Directives“ dem Ansatz der React-Komponenten ähnlich, erfordern aber als Teil des Frameworks eine Angular-Application und einen Controller.

React ist zudem isomorph, das heißt derselbe Code lässt sich mit relativ wenig Aufwand server- oder client-seitig verarbeiten. Die anderen Frameworks arbeiten in der Regel im Client (Browser) und brauchen derzeit – die künftige Version Angular 2.0 soll auch auf dem Server laufen – externe, zum Teil aufwendige Lösungen und Tools, damit ein Server sie verarbeiten kann.

Komponenten für die Web-Anwendung

In der Kapselung von Funktionen, Events und View-Code ähnelt React den W3C-Web-Components. Während diese aber mit ihrem Shadow-DOM nativ im Browser laufen, geht React den umgekehrten Weg und abstrahiert alle DOM-Operationen in seinem Virtual-DOM vom Browser.

React führt alle Operationen zunächst in diesem Virtual-DOM aus. Dann vergleicht es dessen Zustand mit dem des DOMs im Browser und ändert die Unterschiede im Browser-DOM entsprechend ab. Das klingt aufwendig, ist in der Praxis aber performant, da dies viele DOM-Operationen normaler JavaScript-Programmierung einspart. Ein Ansatz, der auch in 3D-Bibliotheken für die Spieleprogrammierung seinen Einsatz findet.

Zusätzlich reduzieren die React-Komponenten die Abhängigkeiten vom Rest der Web-Anwendung. Statt eines Mixes aus HTML, CSS und JavaScript, dessen Code über diverse Dateien verteilt ist, fasst React alle Bestandteile in einer Komponente zusammen. Das steht im Gegensatz zur herrschenden Lehre der Webentwicklung – die JavaScript, HTML und CSS fein säuberlich trennt – und rief entsprechend ablehnende Reaktionen hervor.

Doch dieser Virtual-DOM-Ansatz kann eine Anwendung aus React-Komponenten, etwas jQuery und einem kleinen JS-Router leistungsfähiger machen, als die eines ausgewachsenen JavaScript-MVC-Frameworks. Wenn eine typische MVC-Anwendung Daten aufgrund von Nutzer-Events ändert, ruft sie dazu diverse Controller auf, die ihre Views an den verschiedenen Stellen des DOM-Baums im Browser aktualisieren. React ändert aber nur das Virtual-DOM. Anschließend passt es nur den Teil des DOM-Baums an, dessen Zustand sich unterscheidet.

Da DOM-Operationen zu den langsamsten Elementen einer JavaScript-Anwendung gehören, erscheint React mit seinem Performance-Versprechen – Widerspruch zur herrschenden Lehre hin oder her – sehr attraktiv. So gewinnt React zunehmend Fans in der Entwicklergemeinschaft.

Grundlagen: Hallo Welt

Nach dem Download des Starter-Kits und der Einbindung der nötigen Bibliotheken können React-Einsteiger sofort loslegen. React bringt die XML-artige Template-Sprache JSX mit. Mit dieser können Entwickler JavaScript-Code, CSS und HTML kapseln und modular einsetzen.

React-Code binden Entwickler mit dem script-Tag in das HTML-Dokument ein. Um JSX zu rendern, kommt der eigene Typ „text/jsx“ zur Anwendung. Die React-Bibliothek JSXTransformer.js kompiliert diesen Code zur Laufzeit des Browsers in reines JavaScript.

Das folgende Beispiel definiert eine Klasse „HelloWorld“ mit React.createClass. Ihre Render-Methode gibt das in der Template-Sprache JSX formulierte HTML zurück. JSX ähnelt HTML, ist aber eine eigene XML-artige Sprache mit einigen Syntax-Unterschieden zu HTML. Sie wird zur Laufzeit in JavaScript übersetzt.

Anschließend initialisiert „React.render“ die Klasse als Komponente und fügt sie in das DOM ein. Die Referenzierung der Klasse erfolgt wiederum in einer XML-ähnlichen Schreibweise mit „<HelloWorld/>“ und wird in den div mit der ID „container“ gerendert:

Einstieg: Hello World

<div id="container"></div>`
<script type="text/jsx">`
  var HelloWorld = React.createClass({`
	render: function() {`
	  return (`
		<p>Hallo Welt!</p>`
	  )`
	}`
  });`
  React.render(`
	<HelloWorld/>,`
	document.getElementById('container')`
  );`
</script>`

Listing 1

Die kleine Beispiel-Anwendung von React zieht Bilder von flickr und zeigt sie in einer Art Lightbox. Anhand dieses Beispiels lässt sich die Funktionsweise von React gut erklären.
Die kleine Beispiel-Anwendung von React zieht Bilder von flickr und zeigt sie in einer Art Lightbox. Anhand dieses Beispiels lässt sich die Funktionsweise von React gut erklären.

Die dynamische flickr-Komponente

Um nützlich zu sein, sollten React-Komponenten auch Parameter verarbeiten, Datenstrukturen vorhalten und auf externe Events reagieren können. Dafür stellt React „Props“, Events und den „State“ bereit.

Die folgende, kleine Anwendung besteht aus drei einfachen React-Komponenten, die von flickr die aktuellsten Bilder zu einem bestimmten Tag „abholt“ und als Thumbnail darstellt. Beim Klick auf ein Thumbnail zeigt sie das entsprechende Bild in einer Art Lightbox und schließt sie mit einem Klick auf das Bild wieder.

Den Code dieser kleinen Testanwendung gibt es bei JSBin (dort kann man sie auch ausprobieren) oder in einem gist unter diesem Link. Der Ausgangspunkt ist die Komponente „Flickerer“, die Entwickler wie folgt mit React.render einbinden:

Die Komponente „Flickerer“ einbinden

React.render(
	<Flickerer tag="rp15" />,
	document.getElementById('container')
);

Listing 2

Das Argument tag=rp15 übergibt der Komponente Parameter, die sogenannten *Props* – abgeleitet von „Properties“, also Eigenschaften. Innerhalb einer React-Klasse kann eine Anwendung auf diese Parameter per this.props zugreifen. Mit this.props.tag gibt der JSX-Code im HTML das dargestellte Tag mit aus.

Eigenschaften per Props übergeben

<h2>Neueste Bilder für Tag <i>{this.props.tag}</i>:</h2>

Listing 3

Anhand der Klasse „Flickerer“ lässt sich nun der Lifecycle einer React-Komponente betrachten:

Lifecycle einer Komponente betrachten

var Flickerer = React.createClass({
  getInitialState : function() {
	... Code
  },
  componentDidMount: function() {
	... Code
  },
  render: function() {
	return (
	... JSX-Code zur Darstellung
	)
  }
});

Listing 4

Das Event „getInitialState“ führt grundlegende Operationen unmittelbar nach dem Laden aus. In diesem Beispiel initialisiert dies den „State“ mit einem leeren Array, das später unsere flickr-Bilder aufnimmt: this.state.pics. Der „State“ ist die interne Datenstruktur der React-Komponente. Er lebt quasi in ihr und lässt sich nicht von außen, sondern nur durch Events und Methoden der React-Klasse verändern.

Das Event „componentDidMount“ führt die Komponente aus, sobald das initiale Laden der Komponente in das DOM abgeschlossen ist. Das Beispiel lädt an dieser Stelle die flickr-Bilder für den mit den Props übergebenen Tag. Wenn das abgeschlossen ist, enthält this.state.pics ein Array mit flickr-Thumbnails. Der Befehl „render“ verarbeitet schließlich den Code für die Darstellung der Thumbnails und schreibt HTML in die Seite:

Darstellung der Thumbs rendern

return (
  <div>
  <h2>Neueste Bilder für Tag <i>{this.props.tag}</i>:</h2>
  {
	this.state.pics.map(function(pic) {
	  return (
		<FlickrThumb
		  key={pic.key}
		  image_url={pic.img.media.m.replace("_m", "_q")}
		image_title={pic.img.title} />
	  )
	})
  }
  </div>
)

Listing 5

Neu ist die Iterierung über das Array in this.state.pics. Für jedes Thumbnail lädt die Beispielanwendung nun eine weitere Komponente: <FlickrThumb />. Sie erhält die zur Darstellung nötigen Informationen als Props. JSX und normales JavaScript lassen sich hier gemeinsam in der render-Methode verwenden.

Die Events schließlich initialisieren den Ausgangszustand der Komponente oder verändern durch Reaktion auf externe Browser-Events ihren State. Neben den mitgelieferten Events wie getInitialState oder componentDidMount können Entwickler auch eigene Events als Reaktion auf Nutzereingaben definieren. Diese lassen sich dann ganz altmodisch mit Events wie „onclick“ direkt im HTML implementieren.

In der Beispielkomponente FlickrThumb soll ein Klick auf das Thumbnail das Bild in einer vergrößerten Darstellung öffnen. Dazu bindet man in der Render-Methode per JSX ein Event der Komponente mit „onclick“ an das kleine Bild:

Event an das Bild binden

<img onClick={this.handleClick} />

Listing 6

Die Anweisung „handleClick“ muss als Methode in der Komponente existieren. In diesem Beispiel initialisiert sie die dritte Komponente <FlickrFull /> mit den für das Bild benötigten Props und rendert sie in den div mit der ID „fullpic“:

Bei Klick Bild in Vollansicht zeigen

handleClick : function() {
 React.render( <FlickrFull image_url={this.props.image_url} /> ,
   document.getElementById('fullpic'));
}

Listing 7

Die Komponente <FlickrFull /> enthält ihrerseits Event-Code, um sich im Falle eines Klicks mit dem Event „unmountComponentAtNode“ selbst wieder zu entfernen:

Vollansicht bei Klick schließen

handleClick : function() {
React.unmountComponentAtNode(document.getElementById('fullpic'));
}

Listing 8

Wie bereits beschrieben, behandelt React die in ihm definierten Events stets nur intern am Virtual-DOM. Erst das Endergebnis nach der Verarbeitung übergibt es an das Browser-DOM.

Spätestens seit das Framework React Native im März 2015 erschienen ist, ist die JavaScript-Library React in aller Munde. React Native überführt JSX-Anwendungen in native mobile Apps.
Spätestens seit das Framework React Native im März 2015 erschienen ist, ist die JavaScript-Library React in aller Munde. React Native überführt JSX-Anwendungen in native mobile Apps.

Das React-Ökosystem

Das Kompilieren der JSX-Template-Sprache im Browser zu JavaScript ist relativ langsam. Darum bietet React diverse Möglichkeiten zur Integration von React in Tooling-Umgebungen an. Wer über den node.js-Paket-Manager die sogenannten „react-tools“ installiert, erhält einen Kommandozeilen-JSX-Compiler, der JSX-Code zur Auslieferung auf den Server in reines JavaScript umwandelt. Auch für grunt, gulp und Konsorten gibt es in den Complementary Tools diverse Werkzeuge zur Integration in diese oder für Code-Editoren.

Facebooks Flux wird gerne in einem Atemzug mit React erwähnt, ist aber eine unabhängig davon existierende, unidirektionale Datenfluss-Architektur, die Facebook für client-seitige Web-Anwendungen verwendet. Flux vereinfacht den Informationsfluss zwischen Daten und Views in der Oberfläche. Dazu verarbeitet es diesen nicht (wie Angular und Co) nach einem MVC-Modell, sondern, radikal vereinfacht, über einen zentralen Dispatcher. Diese Architektur können Entwickler unabhängig von React nutzen. React ist aber gut dafür geeignet, weil Facebook es parallel entwickelte und es konzeptionell von den auf Datenflüssen basierenden, reaktiven Paradigma inspiriert ist.

Zudem dient das Framework React Native dazu, in React-Code programmierte Anwendungen in native Apps für iOS, Android und Co. zu überführen. Damit soll es möglich sein, dieselben React-Komponenten in Websites und nativen Apps zu verwenden.

Fazit: Zunächst eigenwillig, aber Ausprobieren lohnt sich

React wirkt anfangs etwas eigenwillig. Die Facebook-Entwickler haben seine gesamte Architektur auf Hochleistung optimiert und dafür einige Dogmen der Webentwicklung über Bord geworfen. Dazu gehört die Trennung von HTML und CSS zur Darstellung sowie JavaScript-Code für die Applikationslogik. Lässt man sich aber darauf ein, lernt man schnell die Vorteile gekapselter Komponenten bei der Entwicklung komplexer Oberflächen zu schätzen.

React ist ein Gegenentwurf aus der Praxis zu den Web Components. Während sich letztere irgendwann nativ im Browser ausführen lassen sollen, macht React das Gegenteil: Es abstrahiert sich vom Browser mit Hilfe seines Virtual-DOM und seiner eigenen Event-Queue. Erst ganz am Ende, wenn React den Zustand seines Virtual-DOMs an das Browser-DOM anpasst, kommt der Browser ins Spiel. Im Gegensatz zu den Web Components des W3C ist React hier und jetzt verfügbar. Da es sich zudem noch mit anderen Technologien und Frameworks einsetzen lässt, gibt es eigentlich keinen Grund, React nicht einfach einmal auszuprobieren.

Ralf Graf
Ralf Graf

arbeitet unter netz8.de als freier Web-Entwickler in Karlsruhe. Er realisiert seit 1996 Web-Sites und -Anwendungen, aktuell mit den Werkzeugen Webstandards, Ruby On Rails, JavaScript und PHP. Er twittert unter @leralle über die Welt als solche und Fußball.

Links und Literatur

  1. React Native
  2. Atom
  3. React Starter-Kit
  4. Testanwendung auf JSBin
  5. Testanwendung bei gist
  6. React Tooling-Integration
  7. Complementary Tools

Finde einen Job, den du liebst zum Thema JavaScript, Webdesign

4 Reaktionen
Tim
Tim

Ist es eigentlich normal, dass allein die JS-Bibliotheken bei React mind. 1mb beanspruchen? Ich hatte mal einen Vergleich zwischen Angular und React gesehen bei dem gerade die Dateigröße ein Argument für React war, jedoch ohne JSX!, für das je nach gewählter Bibliothek gerne mal 600kb bis über 1mb fällig werden. Wenn man einen Node-Server einsetzt kann man sich das ja sparen, aber wenn nicht, finde ich es schon heftig. Das hält mich jedenfalls derzeit noch davon ab React einmal richtig einzusetzten.

Antworten
grep

Hallo ...,

JavaScript (JS) resp. ECMAScript (ES) und in diesem Kontext gerade auch Node.js (werden das Internet) dominieren; Node.js ist weitaus performanter als PHP, ergo ist / wird PHP entbehrlich (sein).

JS bzw. ES und Node.js gehört demnach die Zukunft ... !

Ciao, Sascha.

Antworten
Werner
Werner

php habe ich noch nie vermisst ;-), entbehrlich ist für es mich schon lange. >10 years

ja, recht hast du..Node gefällt.

React Js arbeitet prima mit Rails zusammen.

Empfehlenswert ist auch ein Blick auf Vue Js..erscheint mir in vielen Fällen praktischer und eleganter als React..

Ciao

Antworten
Florian
Florian

Auf die Begründung bin ich gespannt wieso node Performanter sein soll als php.

Könntest du mir das mal eben erläutern?

Antworten
Bitte melde dich an!

Du musst angemeldet sein, um einen Kommentar schreiben zu können.

Jetzt anmelden