React-Native ist ein von Facebook entwickeltes Open-Source-Framework auf Basis von React, mit dem man native Android- und iOS-Apps vollständig in JavaScript entwickeln kann. Damit ist React-Native eine interessante Alternative zu HTML-basierten Cross-Platform-Frameworks.

Wer Software entwickelt und nur eine einzige Zielplattform bedienen muss, hat Glück gehabt. Für viele Entwickler stellt sich aber die Frage, wie sie ihre Anwendung sinnvoll auf mehrere Plattformen bringen können. Je nach Branche und Anwendungsfall müssen Webbrowser, Desktop und mobile Geräte wie Smartphones und Tablets mit ansprechenden Oberflächen versorgt werden. Scheinbar ideal wäre hier eine Technologie, mit der die Anwendung einmal geschrieben und für alle Plattformen wiederverwendet werden könnte. Genau das war die große Versprechung von Java. Mit JavaFX ist das technisch mittlerweile auch tatsächlich sogar möglich, jedoch hat der Ansatz bisher noch keine große Verbreitung gefunden. Durch einige Frameworks wird auch HTML5 als Option für Cross-Plattform-Apps ins Spiel gebracht. Hierbei wird mit JavaScript, CSS und HTML eine Web-Anwendung gebaut, die in einen nativen App-Container gepackt wird. Beim Ausführen der App wird eine WebView-Komponente gestartet, in der die Web-Anwendung ausführt wird. Das jeweilige Framework stellt per JavaScript Schnittstellen zu Gerätefunktionen wie GPS und Filesystem bereit. Des Weiteren werden Stylesheets oder HTML-Komponenten bereitgestellt, damit die App nicht nach „Webseite“, sondern nach „App“ aussieht. Genau hier liegt aber auch der Hase im Pfeffer: Vor allem für mobile Nutzer ist es in vielen Anwendungsfällen wichtig, dass die App sich visuell in das benutzte Betriebssystem nahtlos einfügt. Apple-Benutzer wollen den typischen iOS-Workflow genauso wie Android-Anwender ihre gewohnte Benutzerführung erwarten. Darüber hinaus können Performance-Probleme und Schwierigkeiten beim Einbinden von lokalen Geräte-Ressourcen Argumente gegen HTML5-Cross-Plattform-Ansätze sein. Diese Probleme treten bei nativer Entwicklung für jede der Plattformen nicht auf, jedoch ist auch dieser Ansatz nicht unproblematisch. Zum einen steht der höhere Entwicklungsaufwand im Raum. Die App muss schließlich für jede Plattform von Grund auf neu entwickelt werden. Zwar kommen native Entwickler häufig recht schnell zum Ziel, jedoch in der Regel nur auf ihrer gewohnten Plattform. Folglich müssen für jede Plattform eigene Entwickler mit eigenen Know-How beschäftigt werden.

React-Native

Vor dieser Ausgangssituation bietet React-Native eine interessante Alternative. Natürlich kommt auch React-Native nicht ohne Nachteile daher, jedoch führt der Ansatz zu speziellen Eigenschaften im Entwicklungsprozess und den resultierenden Apps, die eine genaue Betrachtung und Abwägung lohnenswert machen. Wie immer muss natürlich auch hier der konkrete Einsatzzweck berücksichtigt werden. React und React-Native wurden von Facebook entwickelt und als OpenSource zur Verfügung gestellt. React ist eine Bibliothek um UI-Komponenten zu entwickeln, die üblicherweise für Web-Anwendungen zum Einsatz kommt. React-Native setzt auf diese Bibliothek auf und baut ein Framework zum Entwickeln von nativen Mobile-Apps darum. Bei React-Native werden Apps zwar ebenfalls mit JavaScript und CSS programmiert, jedoch ist der Ansatz trotzdem grundlegend anders als bei HTML5-Cross-Plattform-Frameworks. Kurz gesagt: Bei React-Native kommt kein HTML zum Einsatz. Stattdessen werden echte native Oberflächen-Elemente des jeweiligen Betriebssystems gerendert. Schreibt der Entwickler im Code „<Button … >“ dann wird auf Apple-Geräten ein nativer iOS-Button gezeichnet, der genauso aussieht und sich genauso verhält, wie es iOS-Nutzer erwarten würden. Das Gleiche passiert auf Android, ohne dass im Code der Anwendung etwas verändert werden müsste.

Das Rendern von nativen Oberflächenelementen reicht aber noch nicht aus, um wirklich ein Gefühl der Vertrautheit beim Nutzer zu erzeugen. iOS und Android haben in vielen Fällen gänzlich unterschiedliche UI-Konzepte, die so nicht im jeweils anderen System vorkommen. Beispielsweise sind bei neueren Android-Apps so genannte „Floating Action Buttons“ häufig anzutreffen. Damit ist ein über der sonstigen Oberfläche „schwebender“ runder Button gemeint, der schnellen Zugriff auf die Haupt-Aktion der Ansicht ermöglicht. In der Google-Kalender-App ermöglicht der Button beispielsweise das schnelle Hinzufügen eines neuen Termins. Bei iOS ist dieses UI-Element dagegen unüblich. Weitere Beispiele für unterschiedliche UX-Konzepte sind die Navigation innerhalb der App und die Tab-Bar, die sich bei Android üblicherweise oben, bei iOS dagegen unten befindet.
Mit React-Native ist es einfach möglich, nur bestimmte Teile der App Betriebssystem-spezifisch zu halten, während andere Teile übergreifend genutzt werden können. Mit diesem Ansatz sind also nicht alle Teile der App plattformübergreifend aber der Grad an Wiederverwendung kann relativ hoch gehalten werden.
Facebook selbst spricht beispielsweise von 85% Code-Reuse bei einer ihrer Apps.
Es wird also deutlich, dass React-Native nicht den von Java populär gemachten Ansatz „Write-Once-Run-Anywere“ verfolgt. Stattdessen sprechen die Entwickler von „Learn-Once- Write-Everywhere“. Entwickler lernen einmal die Technologie und können dann für alle Plattformen entwickeln. Wer React bereits aus Web-Projekten beherrscht, braucht sich nur noch wenig zusätzliches Wissen aneignen, um auch mobile Apps mit React-Native bauen zu können. Auf der anderen Seite sind Entwickler, die React bisher noch nicht kennen, in der verlockenden Situation, sich gleich drei Plattformen, nämlich Browser, iOS und Android zu erschließen. Unterschiedliche Programmiersprachen und Entwicklungskonzepte für jede einzelne Plattform müssen also nicht mehr erlernt werden.
Soviel zur Motivation, warum man sich mit React-Native befassen sollte. Nun wollen wir einen genaueren Blick auf die Technologie werfen. Der Artikel enthält allerdings kein vollständiges Tutorial, sondern soll lediglich eine Vorstellung der Thematik vermitteln. Dazu wollen wir uns im Folgenden zunächst einmal React (ohne Native) anschauen.

Kurz-Einführung in React

React ist eine JavaScript-Bibliothek um UI-Komponenten zu entwickeln. Es gibt zwei Varianten Komponenten zu bauen: „Funktionale Komponenten“ und „Klassen-Komponenten“. Schauen wir uns beide im Code an:

import React from 'react'
const HelloWorld = (props) => (  
  <div>
    <p>Hello {props.name}</p>
  </div>
)

class HelloWorld extends React.Component {
  render() {
    return (  
      <div>
        <p>Hello {this.props.name}</p>
      </div>
    )
  }
}

Beide Komponenten lassen sich auf die gleiche Weise nutzen:


<div>
  <HelloWorld name="Luise" />
</div>

React-Komponenten sind deklarativ. Sie beschreiben, wie sie selbst in der UI auftauchen sollen. Dazu wird bei funktionalen Komponenten direkt ein Stück DOM zurückgeliefert. Bei Klassen-Komponenten übernimmt diese Aufgabe die zu implementierende „render“-Methode. React-Komponenten besitzen einen Top-Down-Datenfluss von Parent- zu Child-Komponenten. Dies geschieht über so genannte „Props“, die bei der Benutzung der Komponente als Attribute des Tags mitgegeben werden.
Komponenten können beliebig verschachtelt werden. React kümmert sich stets darum, dass bei Datenänderungen die entsprechenden Komponenten performant neugezeichnet werden.
Ein wichtiger Unterschied zu anderen Frameworks wie z.B. Angular ist, dass React keine Template-Sprache benutzt, sondern ausschließlich JavaScript. Um trotzdem im JavaScript-Code XML-ähnliche Tags schreiben zu können, wie in den Beispielen zu sehen ist, wird ein Compiler eingesetzt. Der Compiler wandelt
die Tags in normale Funktionsaufrufe um. Diese „JSX“ genannte Syntax ist also lediglich „syntax-sugar“, um auf der einen Seite angenehm lesbare Tags schreiben zu können, auf der anderen Seite aber keine Templates nutzen zu müssen.

React-Native Komponenten

Komponenten bei React-Native sehen im Prinzip genauso aus wie normale React-Komponenten. Der einzige Unterschied sind die verwendbaren Basis-Tags. Im obigen Code-Beispiel wurden z.B. die Tags „<div>“ und „<p>“ verwendet. Diese sind aber nur im Browser vorhanden. Auf nativen Plattformen ist jedoch kein
HTML-DOM verfügbar.

Aus diesem Grund müssen die eigenen Komponenten aus anderen Grund-Komponenten hergestellt werden. Die beiden wichtigsten sind „View“ und „Text“. Eine React-Native- Komponente könnte damit wie folgt aussehen:

import React from 'react'
import {View, Text} from 'react-native'
const MobileHelloWorld = (props) => (
  <View>
    <Text>Hello {props.name}</Text>
  </View>
)

Die Basis-Komponenten „View“ und „Text“ und viele weitere werden von React-Native bereitgestellt.
Nebenbei: Es existiert auch ein von der Community getriebenes Projekt namens „react-native-web“, welches React-Native für Web-Anwendungen nutzbar machen will. Was zunächst unsinnig erscheint, da React selbst doch bereits für Webanwendungen gedacht ist, aber Hand und Fuß hat. Das Projekt stellt nämlich API-kompatible Basis-Komponenten bereit, mit denen React-Native-Komponenten direkt im Browser benutzt werden können. Statt „div“ und „p“ kann dann auch für Webanwendungen „View“ und „Text“ usw. benutzt werden, was eine noch größere Code-Wiederverwendung ermöglicht. Doch zurück zu mobilen Apps.
Auf die hier gezeigte Art und Weise können wir nun alle Komponenten für unsere App entwickeln. Üblich ist es, jede Komponente in eine eigene JavaScript-Datei zu packen. Hier kommt nun auch der weiter oben bereits angesprochene Mechanismus zum Tragen, mit dem bestimmte Komponenten betriebssystemspezifisch ausgelegt werden können. Dazu wird eine Komponente einfach in zwei Varianten, eine für iOS und eine für Android angelegt. Die Dateinamenskonvention „MyComponent. ios.js“ und „MyComponent.android.js“ anstatt des allgemeinen „MyComponent.js“ sorgt dann dafür, dass auf dem jeweiligen System nur die dafür passende Komponente genutzt wird. Eine Parent-Komponente kann ohne Kenntnis dieses Umstandes ganz normal „MyComponent“ benutzen ohne etwas davon mitzubekommen, dass die Komponente je nach System ganz anders implementiert wurde.

Fazit

React-Native verbindet einige der Vorteile von nativer Entwicklung mit den Vorteilen von Cross-Plattform-Ansätzen, ohne dabei Flexibilität bezüglich Plattformspezifischer Anforderungen einzubüßen.
Darüber hinaus dürfte für den ein oder anderen bereits die Möglichkeit an sich, React benutzen zu können, ausschlaggebend sein. Mit deklarativen Komponenten Programm-Oberflächen mit den Mitteln der funktionalen Programmierung entwickeln zu können ist extrem verlockend. Die React-Community bietet darüber hinaus zahlreiche sehr spannende Ansätze um GUI-Entwicklung an sich neu zu denken, beispielsweise die State-Management-Bibliothek Redux, die eine funktionale Alternative zum klassischen MVC darstellt. Mit React-Native erschließen sich diese und weitere Möglichkeiten auch für Mobile-Entwickler. Ein weiterer Vorteil sind die Developer-Tools, die React-Native mitbringt. Vor allem das Live-Reloading ist hier zu nennen: Während der Entwicklung läuft auf dem Entwicklerrechner ein Dev-Server, der mit der laufenden App im Emulator oder einem angeschlossenem Gerät kommuniziert. Sobald die Entwicklerin den Code im Editor speichert, wird dieser im Hintergrund kompiliert und zur App geschickt. Dort findet unmittelbar ein Reload statt, häufig sogar schneller als man vom Editor zum Emulator wechseln kann. Auf diese Weise ist das Ergebnis der Arbeit unmittelbar sichtbar und Entwickler erhalten schnelles Feedback zu ihren Änderungen. Dabei wird aber nicht immer die gesamte Anwendung neugestartet, sondern nur die Teile im UI ausgetauscht, die sich auch wirklich geändert haben. Der restliche Zustand der App bleibt meistens erhalten. Ein ständiges Navigieren zur aktuellen Ansicht entfällt damit in der Regel.
Die verfügbaren Entwickler-Tools können aber auch als Nachteil angesehen werden. Beispielsweise existiert bisher noch kein mächtiger GUI-Editor, der mit den Editoren der nativen Entwickler vergleichbar wäre. Das grafische „zusammenklicken“ der Oberfläche ist also nicht möglich.
Darüber hinaus sind auch bei React-Native nicht alle nativen Features vollständig verfügbar. Daher muss auch bei React-Native in manchen Fällen wieder auf nativen Code zurückgegriffen werden, wenn man nicht darauf warten möchte, bis die Facebook-Entwickler spezielle Unterstützung für das gewünschte Feature nachliefern. Für viele App-Projekte dürfte der gelieferte Umfang aber sicherlich ausreichend sein.
Es gibt also durchaus Argumente, die je nach Projekt und Ausgangslage für die klassische native Entwicklung und gegen den Einsatz von React-Native sprechen können.
Im Vergleich zu HTML5-basierten Cross-Plattform-Frameworks liegt React-Native dagegen relativ klar vorn. Das einzige wirklich schlagende Argument gegen  React-Native ist die Plattform-Unterstützung: React-Native wird offiziell nur für Android und iOS unterstützt. Aus der Community gibt es darüber hinaus Unterstützung für Windows 10 (sowohl Desktop als auch Mobile) und MacOS Desktop. Wer aber seltenere Betriebssysteme unterstützen muss, findet bei einigen HTML5-Cross-Plattform-Frameworks die bessere Unterstützung.
Den größten Einfluss auf die Entscheidung für oder gegen React-Native dürften in den meisten Firmen zwei Aspekte haben:

  1. Wie wichtig ist eine gute native UX bzw. Performance im Verhältnis zum bereitstehenden Budget?
  2. Über welche Vorkenntnisse verfügen die Entwickler?

Für Projekte, in denen User-Experience und Performance absolute Priorität besitzen und dafür auch größere Ausgaben hingenommen werden können, dürfte ein dediziertes iOS- und Android-Entwicklerteam die beste Wahl sein. Wenn aber das Budget begrenzt ist und trotzdem eine vernünftige UX und Performance erreicht werden soll oder wenn Entwickler bereits im Web oder gar in React Erfahrungen sammeln konnten, dann ist React-Native definitiv eine Überlegung wert.


Manuel MaukyManuel Mauky arbeitet als Softwareentwickler bei der Saxonia-Systems AG in Görlitz. Er beschäftigt sich mit allen Aspekten der Anwendungsentwicklung, wobei derFokus auf dem Frontend liegt, beispielsweise mit JavaFX und modernen JavaScript-Frameworks. Daneben interessieren ihn Themen wie funktionale Programmierung und Softwarearchitektur. Manuel ist Gründungsmitglied und Leiter der Java User Group Görlitz und steuert hierfür und auch für andere Usergroups und Konferenzen regelmäßig Vorträge bei.
Blog: http://www.lestard.eu
Twitter: @manuel_mauky


Diesen Artikel finden Sie auch in der Erstausgabe der JAVAPRO. Einfach hier kostenlos bestellen.

 

 

(Visited 428 times, 1 visits today)

Leave a Reply