Reagieren Sie auf das Entwicklungshandbuch für native Webanwendungen

Du bist aufgewacht. Die Sonne scheint, die Vögel zwitschern. In der Welt befindet sich niemand im Krieg mit irgendjemandem, niemand hungert und der gleiche Code kann in Webprojekten und in nativen Anwendungen verwendet werden. Wie schön wäre es! Leider ist am Horizont nur universeller Code zu sehen, aber der Weg dorthin ist auch heute noch voller Überraschungen.

Bild

Das Material, dessen Übersetzung wir heute veröffentlichen, ist eine kleine, aber recht detaillierte Anleitung zur Entwicklung universeller Anwendungen mit React Native.

Warum ist das alles?


Die Abkürzung "PWA" ( Progressive Web Apps , Progressive Web Applications) ist heute allen bekannt. Dieses aus drei Buchstaben bestehende Akronym scheint nur ein Wal in einem Meer technischer Begriffe zu sein. Diese beliebte Technologie ist jedoch immer noch nicht ohne Mängel . Mit solchen Anwendungen sind viele technologische Schwierigkeiten verbunden. Es gibt Situationen, in denen ein Entwickler gezwungen ist, gleichzeitig native Anwendungen und Webanwendungen zu erstellen. Hier ist ein guter Artikel zum Vergleich von PWA und nativen Anwendungen.

Vielleicht sollte sich das Geschäft nur auf native Anwendungen konzentrieren? Nein, das ist es nicht wert. Das ist ein großer Fehler. Infolgedessen wird die Entwicklung einer einzigen universellen Anwendung zu einem logischen Schritt. Auf diese Weise können Sie die Entwicklungszeit verkürzen und die Kosten für die Erstellung und Unterstützung von Projekten senken. Es sind diese Eigenschaften universeller Anwendungen, die mich zu einem kleinen Experiment veranlasst haben.

Dies ist ein universelles Anwendungsbeispiel aus dem Bereich des elektronischen Handels für die Bestellung von Lebensmitteln. Nach dem Experiment habe ich eine Vorlage für zukünftige Projekte und für die weitere Forschung erstellt.


Papu ist eine Anwendung zum Bestellen von Lebensmitteln für Android, iOS und das Internet

Anwendungsbausteine


Hier verwenden wir React, daher müssen wir die Anwendungslogik von der Benutzeroberfläche trennen. Es ist am besten, ein System zu verwenden, um den Status einer Anwendung wie Redux oder Mobx zu steuern. Ein solcher Schritt macht die Logik der Anwendung sofort universell. Es kann ohne Änderungen auf verschiedenen Plattformen verwendet werden.

Der visuelle Teil der Anwendung ist eine weitere Konversation. Um die Anwendungsschnittstelle zu erstellen, benötigen Sie einen universellen Satz von Grundelementen, Grundbausteinen. Sie sollten sowohl im Web als auch in der nativen Umgebung funktionieren. Leider sind die Sprache des Webs und die Sprache der nativen Plattformen zwei verschiedene Dinge.

Ein Standard-Webcontainer wird Sie beispielsweise folgendermaßen kontaktieren:

<div> !  -   !</div> 

Und einheimisch - so:

 <View>!  -    React Native</View> 

Einige kluge Leute haben einen Ausweg aus dieser Situation gefunden. Die Ausgabe waren spezialisierte Elementbibliotheken. Einer meiner Favoriten ist die wunderbare React Native Web Library. Es kümmert sich nicht nur um die Grundelemente der Anwendung und ermöglicht die Verwendung von React Native-Komponenten im Web (nicht alle Komponenten!), Sondern bietet auch Zugriff auf verschiedene React Native-APIs. Unter ihnen sind Geolocation , Platform , Animated , AsyncStorage und viele andere. Schauen Sie sich die großartigen Beispiele an, die im Handbuch für diese Bibliothek zu finden sind.

Muster


Wir haben die Primitiven herausgefunden. Wir müssen jedoch noch die Umgebung für die Webentwicklung und die native Entwicklung verbinden. Mein Projekt verwendet die Create- React -App (für eine Webanwendung) und ein Initialisierungsskript von React Native (für eine native Anwendung ohne Expo). Zuerst habe ich ein Projekt mit diesem Befehl erstellt: create-react-app rnw_web . Dann erstellte er ein zweites Projekt: react-native init raw_native . Dann habe ich nach dem Beispiel von Victor Frankenstein die package.json Dateien aus diesen beiden Projekten genommen und zusammengeführt. Danach habe ich im Ordner des neuen Projekts die neue yarn eingezogen. Hier ist die betreffende package :

 { "name": "rnw_boilerplate", "version": "0.1.0", "private": true, "dependencies": {   "react": "^16.5.1",   "react-art": "^16.5.1",   "react-dom": "^16.5.1",   "react-native": "0.56.0",   "react-native-web": "^0.9.0",   "react-navigation": "^2.17.0",   "react-router-dom": "^4.3.1",   "react-router-modal": "^1.4.2" }, "devDependencies": {   "babel-jest": "^23.4.0",   "babel-preset-react-native": "^5",   "jest": "^23.4.1",   "react-scripts": "1.1.5",   "react-test-renderer": "^16.3.1" }, "scripts": {   "start": "node node_modules/react-native/local-cli/cli.js start",   "test": "jest",   "start-ios": "react-native run-ios",   "start-web": "react-scripts start",   "build": "react-scripts build",   "test-web": "react-scripts test --env=jsdom",   "eject-web": "react-scripts eject" } } 

Bitte beachten Sie, dass diese Version der Datei keine Navigationsfunktionen enthält. Als Nächstes müssen Sie alle Quellcodedateien aus den Ordnern der Webanwendung und der nativen Anwendung in den Ordner des neuen einheitlichen Projekts kopieren.


Ordner, die in ein neues Projekt kopiert werden sollen

Erstellen Sie nun im Ordner src , der sich im Verzeichnis des neuen Projekts befindet, zwei Dateien: App.js und App.native.js . Dank Webpack können wir Dateinamenerweiterungen verwenden, um dem Bundler mitzuteilen, wo welche Dateien verwendet werden sollen. Das Trennen von App Dateien ist von entscheidender Bedeutung, da wir für die Navigation in Apps unterschiedliche Ansätze verwenden werden.

Hier ist die App.js Datei für das Web. react-router zur Navigation verwendet.

 // App.js - WEB import React, { Component } from "react"; import { View } from "react-native"; import WebRoutesGenerator from "./NativeWebRouteWrapper/index"; import { ModalContainer } from "react-router-modal"; import HomeScreen from "./HomeScreen"; import TopNav from "./TopNav"; import SecondScreen from "./SecondScreen"; import UserScreen from "./UserScreen"; import DasModalScreen from "./DasModalScreen"; const routeMap = { Home: {   component: HomeScreen,   path: "/",   exact: true }, Second: {   component: SecondScreen,   path: "/second" }, User: {   component: UserScreen,   path: "/user/:name?",   exact: true }, DasModal: {   component: DasModalScreen,   path: "*/dasmodal",   modal: true } }; class App extends Component { render() {   return (     <View>       <TopNav />       {WebRoutesGenerator({ routeMap })}       <ModalContainer />     </View>   ); } } export default App; 

Hier ist die App.js für die React Native App. Hier wird die react-navigation .

 // App.js - React Native import React, { Component } from "react"; import { createStackNavigator, createBottomTabNavigator } from "react-navigation"; import HomeScreen from "./HomeScreen"; import DasModalScreen from "./DasModalScreen"; import SecondScreen from "./SecondScreen"; import UserScreen from "./UserScreen"; const HomeStack = createStackNavigator({ Home: { screen: HomeScreen, navigationOptions: { title: "Home" } } }); const SecondStack = createStackNavigator({ Second: { screen: SecondScreen, navigationOptions: { title: "Second" } }, User: { screen: UserScreen, navigationOptions: { title: "User" } } }); const TabNav = createBottomTabNavigator({ Home: HomeStack, SecondStack: SecondStack }); const RootStack = createStackNavigator( {   Main: TabNav,   DasModal: DasModalScreen }, {   mode: "modal",   headerMode: "none" } ); class App extends Component { render() {   return <RootStack />; } } export default App; 

So habe ich eine einfache Anwendungsvorlage erstellt und die Plattform für die weitere Arbeit vorbereitet. Sie können diese Vorlage ausprobieren, indem Sie sich dieses Repository ansehen.

Jetzt werden wir diese Vorlage etwas komplizieren und ein Routing- / Navigationssystem hinzufügen.

Navigationsprobleme und ihre Lösungen


Eine Anwendung benötigt, sofern sie nicht aus einem einzigen Bildschirm besteht, eine Art Navigationssystem. Jetzt (wir sprechen über September 2018) gibt es nur ein solches universelles Arbeitssystem, das sowohl für das Web als auch für native Anwendungen geeignet ist. Es geht um den React Router . Für das Web funktioniert diese Lösung gut, aber bei React Native-Projekten ist nicht alles so klar.

In React Router Native gibt es keine Übergänge zwischen Bildschirmen, es gibt keine Unterstützung für die Schaltfläche Zurück (für die Android-Plattform), es gibt keine modalen Bildschirme, Navigationsleisten und andere Funktionen. Andere Navigationswerkzeuge wie React Navigation verfügen über diese Funktionen.

Ich habe diese spezielle Bibliothek benutzt, aber Sie können etwas anderes aufgreifen. Daher ist in meinem Projekt React Router für die Navigation in der Webanwendung und React Navigation für die Navigation in der nativen Anwendung verantwortlich. Dies schafft jedoch ein neues Problem. Tatsache ist, dass die Ansätze zur Navigation und zur Übertragung von Parametern in diesen Systemen sehr unterschiedlich sind.

Um den Geist von React Native Web zu bewahren und überall einen ähnlichen Ansatz wie in nativen Anwendungen zu verwenden, habe ich mich der Lösung dieses Problems zugewandt, indem ich Webrouten erstellt und in HOC verpackt habe. Dies gab mir die Möglichkeit, eine API zu erstellen, die an React Navigation erinnert.

Dieser Ansatz ermöglichte es mir, zwischen den Bildschirmen einer Webanwendung zu wechseln, sodass keine separaten Komponenten für zwei Arten von Anwendungen erstellt werden mussten.

Der erste Schritt bei der Implementierung dieses Mechanismus besteht darin, ein Objekt mit einer Beschreibung der Routen für die Webanwendung zu erstellen:

 import WebRoutesGenerator from "./NativeWebRouteWrapper"; //   ,    React Router     HOC const routeMap = { Home: {   screen: HomeScreen,   path: '/',   exact: true }, Menu: {   screen: MenuScreen,   path: '/menu/sectionIndex?' } } //  render <View> {WebRoutesGenerator({ routeMap })} </View> 

In der Tat ist hier eine Kopie der React Navigation-Erstellungsfunktion mit zusätzlichen React Router-spezifischen Funktionen.

Als Nächstes erstelle ich mit meiner Hilfsfunktion react-router Routen und verpacke sie in HOC. Auf diese Weise können Sie die screen klonen und ihren Eigenschaften eine navigation hinzufügen. Dieser Ansatz ahmt das Verhalten von React Navigation nach und stellt Methoden wie goBack() , getParam() , getParam() .

Modale Bildschirme


React Navigation ermöglicht dank createStackNavigator , dass eine bestimmte Seite der Anwendung in Form eines modalen Bildschirms von unten angezeigt wird. Um dies in einer Webanwendung zu erreichen, musste ich die React Router Modal- Bibliothek verwenden. Um mit dem modalen Bildschirm zu arbeiten, müssen Sie dem routeMap Objekt zunächst die entsprechende Option routeMap :

 const routeMap = { Modal: {   screen: ModalScreen,   path: '*/modal',   modal: true //    ModalRoute     } } 

Außerdem muss die <ModalContainer /> -Komponente aus der <ModalContainer /> react-router-modal Bibliothek zum Anwendungslayout hinzugefügt werden. Dort wird die entsprechende Seite angezeigt.

Navigation zwischen Bildschirmen


Dank des HOC unserer Entwicklung (vorübergehend heißt diese Komponente NativeWebRouteWrapper , und dies ist übrigens ein schrecklicher Name) können wir fast dieselben Funktionen wie in React Navigation verwenden, um die Bewegung zwischen Seiten in der Webversion der Anwendung zu organisieren:

 const { product, navigation } = this.props <Button onPress={navigation.navigate('ProductScreen', {id: product.id})} title={`Go to ${product.name}`} /> <Button onPress={navigation.goBack} title="Go Back" /> 

Kehren Sie zum vorherigen Bildschirm zurück.


In React Navigation können Sie zu n Bildschirmen zurückkehren, die sich im Navigationsstapel befinden. Ähnlich ist in React Router nicht verfügbar, es gibt keinen Navigationsstapel. Um dieses Problem zu lösen, müssen wir die pop Funktion unseres eigenen Designs in den Code importieren. Wenn wir sie anrufen, geben wir ihr verschiedene Parameter:

 import pop from '/NativeWebRouteWrapper/pop' render() { const { navigation } = this.props return (   <Button     onPress={pop({screen: 'FirstScreen', n: 2, navigation})}     title="Go back two screens"   /> ) } 

Wir beschreiben diese Parameter:

  • screen - Der Name des Bildschirms (wird von React Router in der Webversion der Anwendung verwendet).
  • n ist die Anzahl der Bildschirme, die mithilfe des Stapels (mithilfe von React Navigation) zurückgegeben werden sollen.
  • navigation - ein Objekt, das Navigation bietet.

Arbeitsergebnisse


Wenn Sie mit der hier vorgestellten Idee der Entwicklung universeller Anwendungen experimentieren möchten, habe ich zwei Vorlagen erstellt.

Die erste ist eine saubere, universelle Umgebung für die Entwicklung von Webanwendungen und nativen Anwendungen.

Die zweite ist im Wesentlichen die erste Vorlage, die aufgrund meines Systems zur Organisation der Navigation in der Anwendung erweitert wurde.

Hier ist eine Papu-Demo-Anwendung, die auf den obigen Überlegungen basiert. Es ist voller Fehler und Sackgassen, aber Sie können es selbst zusammenstellen, in einem Browser und auf einem mobilen Gerät ausführen und sich in der Praxis ein Bild davon machen, wie alles funktioniert.

Zusammenfassung


Die React-Entwickler-Community benötigt natürlich eine universelle Bibliothek für die Organisation der Anwendungsnavigation, da dies die Entwicklung von Projekten wie dem, über das wir gesprochen haben, vereinfacht. Es wäre sehr schön, wenn die React Navigation-Bibliothek im Web funktionieren würde (tatsächlich ist diese Funktion bereits verfügbar , aber die Arbeit damit ist nicht ohne Schwierigkeiten).

Liebe Leser! Nutzen Sie React, um universelle Anwendungen zu erstellen?

Source: https://habr.com/ru/post/de428568/


All Articles