ClickCease
Share on linkedin
Share on facebook
Share on twitter
Share on email

Codesharing zwischen React und React Native

Jean Damke

Jean Damke

Sharing code between React and React Native

Als Front-End- oder Full-Stack-Entwickler stößt vermutlich jeder irgendwann auf ein Projekt, bei dem mehrere Plattformen entwickelt werden müssen, wie z.B. bei Web und Mobile. Bis vor Kurzem hätten Sie dabei die Wahl gehabt, mindestens drei verschiedene Anwendungen zu entwickeln, eine für Web, eine für Android und eine für iOS. In diesem Beitrag widmen wir uns der Anwendung React Native. 

Erfreulicherweise gibt es inzwischen einige Initiativen, die versuchen, den Code zwischen verschiedenen Plattformen zu vereinheitlichen. Eine der prominentesten ist React Native.

 

React Native

React Native vereinheitlicht die Entwicklung mobiler Anwendungen. Das bedeutet, dass es genügt, eine einzige Anwendung sowohl für Android als auch für iOS zu entwickeln. Es gibt auch ein Projekt, das die Entwicklung für Windows 10 ermöglicht. 

Wenn es um Codesharing geht, ist der Web-Anteil allerdings noch immer isoliert. Wie Sie sich anhand der Namen vorstellen können, haben React und React Native viele Gemeinsamkeiten, die eine Art Austausch von Code zwischen Mobile- und Web-Entwicklung ermöglichen. Der erste Schritt zum Verständnis von Codesharing besteht darin, die Gemeinsamkeiten zu verstehen. Übrigens ist das Motto von React „Einmal lernen, überall schreiben“, wie man an der Notwendigkeit eines solchen Beitrags erkennen kann, nicht ganz richtig. 



React und React Native im Vergleich

Code in React und React Native zu schreiben ist ziemlich ähnlich. Der grundlegende Unterschied besteht darin, dass man in React HTML-Elemente rendert, während man in React Native stattdessen vordefinierte Komponenten rendert, die aus der React Native-Bibliothek importiert wurden. Die Liste der Komponenten können Sie auf der React Native-Website einsehen.

In der folgenden Abbildung sehen Sie einen Vergleich zweier Komponenten, eine für React und die andere für React Native, die versuchen, die gleiche Funktionalität zu erreichen. Man kann leicht Analogien zwischen den von jeder Komponente verwendeten Komponenten erkennen, wie z.B. die Äquivalenz zwischen <div> und <view> Elementen.

Examples of a simple component in React
Beispiele für eine einfache Komponente in React
Beispiele für eine einfache Komponente in React
Beispiele für eine einfache Komponente in React Native

Ein weiterer Unterschied ist die Art und Weise, wie die Komponenten mit CSS umgehen. React ist flexibler und bietet die Möglichkeit, CSS auf verschiedene Art und Weise zu handhaben und CSS-Präprozessoren zu verwenden. React Native hat wiederum einige starre Regeln, wenn es um das Styling der Komponenten geht.

Hier bieten sich Ihnen einige Möglichkeiten, CSS in React zu stylen.

Mit classNames, die mit Sass, Less oder jedem anderen CSS-Präprozessor kombiniert werden können:

Styling in React mit className
Styling in React mit className
Example of the content of a CSS file
Beispiel für den Inhalt einer CSS-Datei

Mit Inline-Styling, das direkt in den Elementen selbst erreicht werden kann, wie in der Abbildung unten.

Direct inline styling in React
Direktes Iinline Styling in React

Oder isoliert in ein separates Objekt oder sogar in eine Datei.

Inline styling in React using a styles object
Inline Styling in React unter Verwendung eines Styles-Objekts

Additionally, you could use libraries such as Styled Components to enhance the usage of styling in React.

Bei React Native besteht jedoch nicht die Möglichkeit, mittels ClassNames und CSS-Präprozessoren zu stylen. Stattdessen können wir Inline-Styles direkt in den Komponenten verwenden oder besser: die Funktion Stylesheet.create() nutzen und die Objekte wie im Bild gezeigt übergeben:

Styling in React Native
Styling in React Native

Außerdem ist die für React erwähnte Stilkomponenten-Bibliothek auch für React Native verfügbar.


Wie man Code teilt

Nun zum wichtigen Teil: Wie können wir den Code teilen? In den Beispielen haben Sie vielleicht schon erkannt, dass die Logik beider Komponenten sowie der Code für diese Logik genau gleich ist. Warum also zweimal schreiben?

Hier ein Beispiel dafür, wie Code geteilt werden kann, indem die Logik in eine Komponente aufgeteilt wird und zwei spezialisierte Komponenten für die visuellen Teile jeder Anwendung vorhanden sind.

Example of a container component for sharing code
Beispiel für eine Containerkomponente zum Teilen von Code
Examples of equivalent visual components for React
Beispiele für äquivalente visuelle Komponenten für React
Examples of equivalent visual components for React Native
Beispiele für äquivalente visuelle Komponenten für React Native

Aus den obigen Bildern wird deutlich, dass wir nur eine logische Komponente zusammen mit zwei visuellen Komponenten als Unterobjekte der ersten verwenden können, die entweder Web- oder Anwendungskomponenten rendern, je nachdem, welche Plattform verwendet wird. Dies kann entweder mit Klassen- oder mit Funktionskomponenten geschehen, mit oder ohne Redux. Alles, was die Komponentenlogik betrifft und in React vorhanden ist, wird nämlich auch von React Native akzeptiert.

In diesem Parent-Child-Szenario haben wir einen mächtigen Verbündeten: Babel. Mit Babel kann man die Importfunktion auf die Parent-Komponente anwenden, ohne sich um irgendeine Art von bedingter Verwendung der Komponente kümmern zu müssen. Babel kann automatisch entscheiden, welchen Import Sie für die Elternkomponente verwenden möchten, je nachdem, wie Sie ihr Projekt aufbauen. Dazu können Sie einfach beide Komponenten, Web und Anwendung im selben Ordner mit unterschiedlichen Erweiterungen haben. Eine mit „.js“ (oder „.ts“, wenn Sie TypeScript verwenden), und eine mit „.native.js“ (oder „.native.ts“). Sie können dieses Muster in der übergeordneten Komponente des oben erwähnten Beispiels sehen.

Hooks

Wenn Sie Hooks verwenden, können Sie die Logik auch in einen benutzerdefinierten Hook trennen und die notwendigen Variablen und Funktionen zurückgeben, die Sie für ihre Logik benötigen. Dieses Verhalten können Sie im Beispiel unten sehen. Hier können Sie mehr über benutzerdefinierte Hooks lesen.

Examples of visual components using a custom hook in React
Beispiele für visuelle Komponenten mit einem benutzerdefinierten Hook in React
Examples of visual components using a custom hook in React Native
Beispiele für visuelle Komponenten mit einem benutzerdefinierten Hook in React Native
Example of a custom hook that can be used by components in React and React Native
Beispiele für einen benutzerdefinierten Hook, der von Komponenten in React und React Native verwendet werden kann.

Der Vorteil dieser Methode im Vergleich zur Parent-Child-Methode besteht darin, dass wir nicht darauf angewiesen sind, dass sich die Dateien im gleichen Ordner befinden, damit Babel sie interpretieren kann. Dadurch haben Sie die Möglichkeit, sie ohne Probleme in verschiedenen Repositories zu haben. Das kann für viele Anwendungsfälle recht nützlich sein.


Das Teilen von CSS

Um auf das CSS zurückzukommen, wir haben gesehen, dass React und React Native eine Möglichkeit haben, gemeinsame Styles zu verwenden. Dies geschieht, indem ein Style in einem JSON-Objekt deklariert und in das style-Attribut der Komponenten geladen wird. Um ein gemeinsames Stylesheet zu erreichen, könnten wir die Styles wie in der Abbildung unten verwenden.

Example of a possible way to share CSS
Beispiel für eine mögliche Art CSS zu teilen

Es wäre sogar möglich, das Objekt zu erweitern, um zwei getrennte Styles zu erreichen, die auf einem gemeinsamen geteilten Style basieren. Die gemeinsame Nutzung von Styles ist jedoch etwas, das möglicherweise zu schwer zu pflegen ist und vielleicht sogar mehr Zeit erfordert, als zwei völlig getrennte Style-Definitionen zu verwalten. Wenn Sie eine Vereinheitlichung anstreben, bedenken Sie, dass es ein nicht so lohnender Weg sein könnte.


Anwendungsfall: WordPress hinzufügen

Bei SPRYLAB stellte das Projekt, das wir uns für die gemeinsame Nutzung von Code vorstellten, eine große Herausforderung dar. Unser Kunde wollte die Flexibilität haben, die Komponenten auf seiner Website nach seinem eigenen Willen neu anzuordnen. Daher entschied sich das Team für die Verwendung von WordPress für den Webteil der Anwendung. Das bedeutete, dass es beim Versuch, den Code zu teilen, mehrere Herausforderungen gab.

Momentan verwendet WordPress zum Rendern seiner Widgets React. Jedes Widget wird jedoch separat aus den PHP-Dateien geladen und wie eine separate React-Instanz behandelt. Das bedeutet, dass der Teil der Anwendung, der alle Komponenten vereint, von PHP und nicht von JavaScript behandelt wird. So wären wir nicht in der Lage, einen einzigen Kontext oder Speicher zu haben, um die Zustände zwischen den notwendigen Komponenten zu teilen. Wir sind daher zu dem Schluss gekommen, dass der Teil der Logik, den wir teilen könnten, eine Zwischenebene zwischen einem globalen Zustand und den visuellen Komponenten darstellen würde. Die Zeit, die wir dafür aufwenden müssten, um dies zu bewerkstelligen, wäre jedoch vergleichbar mit der Zeit, die wir für die Erstellung völlig isolierter Logiken aufwenden müssten.

In unserem speziellen Fall haben wir schließlich entschieden, dass es sich nicht lohnte, ganze Komponenten gemeinsam zu nutzen. So blieben wir bei der gemeinsamen Nutzung einiger spezifischer Funktionen, insbesondere derjenigen, die die Backend-API-Aufrufe machten. Wir hatten auch TypeScript-Definitionen, Lokalisierungsdateien, Assets und Konfigurationsfunktionen in unserem gemeinsam genutzten Repository, die wir mit der Option „git+ssh“ für unsere package.json-Dateien problemlos zu jedem der spezifischen Repositories hinzufügten.

Rückblickend wäre es vielleicht möglich gewesen, zusätzliche benutzerdefinierte Funktionen/Hooks zu verwenden, ähnlich dem „Anwendungsbeispiel“, das in einem der obigen Bilder dargestellt ist und diese Funktionen in jedem Teil zu erweitern, wann immer es notwendig ist. Allerdings wären wir immer noch recht eingeschränkt, indem was wir tun könnten.


Nächster Schritt: Den Code vereinheitlichen

Zum Abschluss dieses Blogbeitrags wollen wir neben der gemeinsamen Nutzung von Code auch den einzigen einheitlichen Code ansprechen. Gegenwärtig kann dies mit Bibliotheken wie React Native for Web erreicht werden. Diese ermöglichen das Schreiben eines einzigen React Native-Codes, der für das Web konvertiert wird. Flutter, ein neues Framework von Google, gilt als Antwort auf React Native und soll das Thema unseres nächsten Blogbeitrags sein.

Kontaktieren Sie uns
Wie können wir helfen?

Herausfordernde Plattform- und App-Projekte treiben uns an. Wenn Sie auf der Suche nach einer Agentur sind, mit der Sie Ihr Geschäftsmodell digitialisieren wollen, sind wir der richtige Partner.