Guía de desarrollo de aplicaciones web React Native

Te despertaste El sol brilla, los pájaros cantan. En el mundo, nadie está en guerra con nadie, nadie está muriendo de hambre, y el mismo código se puede usar en proyectos web y en aplicaciones nativas. ¡Qué lindo sería! Desafortunadamente, solo se puede ver un código universal en el horizonte, pero el camino hacia él, incluso hoy, todavía está lleno de sorpresas.

imagen

El material, cuya traducción publicamos hoy, es una guía pequeña pero bastante detallada para el desarrollo de aplicaciones universales usando React Native.

¿Por qué es todo esto?


La abreviatura "PWA" ( Progressive Web Apps , aplicaciones web progresivas) hoy es bien conocida por todos, este acrónimo de tres letras parece ser solo una ballena en un mar de términos técnicos. Pero esta tecnología popular todavía no está exenta de defectos . Hay muchas dificultades tecnológicas asociadas con tales aplicaciones; hay situaciones en las que un desarrollador se ve obligado a crear simultáneamente aplicaciones nativas y web. Aquí hay un buen artículo que compara PWA y aplicaciones nativas.

¿Quizás las empresas deberían centrarse solo en las aplicaciones nativas? No, no vale la pena. Este es un gran error. Como resultado, el desarrollo de una sola aplicación universal se convierte en un paso lógico. Esto le permite reducir el tiempo de desarrollo, reducir el costo de crear y apoyar proyectos. Son estas características de las aplicaciones universales las que me llevaron a un pequeño experimento.

Este es un ejemplo de aplicación universal del campo del comercio electrónico para pedir comida. Después del experimento, creé una plantilla para futuros proyectos y para futuras investigaciones.


Papu es una aplicación de pedidos de alimentos diseñada para Android, iOS y la web.

Bloques de construcción de aplicaciones


Aquí usamos React, por lo que debemos separar la lógica de la aplicación de la interfaz de usuario. Es mejor utilizar algún tipo de sistema para controlar el estado de una aplicación como Redux o Mobx. Tal movimiento inmediatamente hace que la lógica del funcionamiento de la aplicación sea universal. Sin cambios, se puede usar en diferentes plataformas.

La parte visual de la aplicación es otra conversación. Para construir la interfaz de la aplicación, debe tener un conjunto universal de primitivas, bloques de construcción básicos. Deben funcionar tanto en la web como en el entorno nativo. Desafortunadamente, el lenguaje de la web y el lenguaje de las plataformas nativas son dos cosas diferentes.

Por ejemplo, un contenedor web estándar lo contactará así:

<div> !  -   !</div> 

Y nativo, así:

 <View>!  -    React Native</View> 

Algunas personas inteligentes han encontrado una salida a esta situación. La salida fue bibliotecas de elementos especializados. Uno de mis favoritos es la maravillosa biblioteca web React Native . No solo se ocupa de las primitivas básicas de la aplicación, permitiendo el uso de componentes React Native en la web (¡no todos los componentes!), Sino que también da acceso a varias API React Native. Entre ellos se encuentran Geolocation , Platform , Animated , AsyncStorage y muchos otros. Eche un vistazo a los excelentes ejemplos que se pueden encontrar en el manual de esta biblioteca.

Patrón


Descubrimos las primitivas. Pero aún necesitamos conectar el entorno para el desarrollo web y el desarrollo nativo. Mi proyecto utiliza create-react-app (para una aplicación web) y un script de inicialización React Native (para una aplicación nativa, sin Expo). Primero, creé un proyecto con este comando: create-react-app rnw_web . Luego creó un segundo proyecto: react-native init raw_native . Luego, siguiendo el ejemplo de Victor Frankenstein, tomé los archivos package.json de estos dos proyectos y los fusioné. Después de eso, en la carpeta del nuevo proyecto, introduje el nuevo archivo de yarn . Aquí está el archivo del package en cuestión:

 { "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" } } 

Tenga en cuenta que no hay funciones de navegación en esta versión del archivo. A continuación, debe copiar todos los archivos de código fuente de las carpetas de la aplicación web y la aplicación nativa a la carpeta del nuevo proyecto unificado.


Carpetas para copiar a un nuevo proyecto

Ahora, en la carpeta src , que se encuentra en el directorio del nuevo proyecto, cree dos archivos: App.js y App.native.js . Gracias a webpack, podemos usar extensiones de nombre de archivo para indicarle al agrupador dónde usar los archivos. Separar los archivos de la App es vital ya que vamos a utilizar diferentes enfoques para navegar por las aplicaciones.

Aquí está el archivo App.js para la web. react-router utiliza para la navegación.

 // 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; 

Aquí está el App.js para la aplicación React Native. Aquí react-navigation utiliza 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; 

Así es como creé una plantilla de aplicación simple y preparé la plataforma para seguir trabajando. Puede probar esta plantilla mirando este repositorio.

Ahora complicaremos un poco esta plantilla, agregaremos un sistema de enrutamiento / navegación.

Problemas de navegación y sus soluciones.


Una aplicación, a menos que consista en una sola pantalla, necesita algún tipo de sistema de navegación. Ahora (estamos hablando de septiembre de 2018) solo hay un sistema de trabajo universal, adecuado para aplicaciones web y nativas. Se trata del React Router . Para la web, esta solución funciona bien, pero en el caso de los proyectos React Native, no todo está tan claro.

En React Router Native no hay transiciones entre pantallas, no hay soporte para el botón Atrás (para la plataforma Android), no hay pantallas modales, barras de navegación y otras características. Otras herramientas de navegación, como React Navigation , tienen estas capacidades.

Usé esta biblioteca en particular, pero puedes elegir otra cosa. Por lo tanto, en mi proyecto, React Router es responsable de la navegación en la aplicación web y React Navigation para la navegación en la aplicación nativa. Esto, sin embargo, crea un nuevo problema. El hecho es que los enfoques para la navegación y la transferencia de parámetros en estos sistemas son muy diferentes.

Para preservar el espíritu de React Native Web, utilizando en todas partes un enfoque similar al utilizado en aplicaciones nativas, abordé la solución de este problema creando rutas web y envolviéndolas en HOC. Esto me dio la oportunidad de crear una API similar a React Navigation.

Este enfoque me permitió moverme entre las pantallas de una aplicación web, eliminando la necesidad de crear componentes separados para dos tipos de aplicaciones.

El primer paso para implementar este mecanismo es crear un objeto con una descripción de las rutas para la aplicación web:

 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> 

De hecho, aquí hay una copia de la función de creación React Navigation con la adición de capacidades específicas de React Router.

Luego, usando mi función de ayuda, creo rutas de react-router y las envuelvo en HOC. Esto le permite clonar el componente de la screen y agregar navigation a sus propiedades. Este enfoque imita el comportamiento de React Navigation y hace que métodos como navigate() , goBack() , getParam() .

Pantallas modales


React Navigation, gracias a createStackNavigator , hace posible que cierta página de la aplicación createStackNavigator desde abajo en forma de pantalla modal. Para lograr esto en una aplicación web, tuve que usar la biblioteca Modal React Router . Para trabajar con la pantalla modal, primero debe agregar la opción adecuada al objeto routeMap :

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

Además, el <ModalContainer /> de la biblioteca react-router-modal debe agregarse al diseño de la aplicación. La página correspondiente se mostrará allí.

Navegación entre pantallas


Gracias al HOC de nuestro desarrollo (temporalmente este componente se llama NativeWebRouteWrapper , y este, por cierto, es un nombre terrible), podemos usar casi el mismo conjunto de funciones que en React Navigation para organizar el movimiento entre páginas en la versión web de la aplicación:

 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" /> 

Regresar a la pantalla anterior.


En React Navigation, puede volver a n pantallas que están en la pila de navegación. Similar en React Router no está disponible, no hay pila de navegación. Para resolver este problema, necesitamos importar la función pop de nuestro propio diseño en el código. Al llamarla, le daremos varios parámetros:

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

Describimos estos parámetros:

  • screen : el nombre de la pantalla (utilizada por React Router en la versión web de la aplicación).
  • n es el número de pantallas que se devuelven usando la pila (usando React Navigation).
  • navigation : un objeto que proporciona navegación.

Resultados de trabajo


Si desea experimentar con la idea de desarrollar aplicaciones universales presentadas aquí, creé dos plantillas.

El primero es un entorno limpio y universal para desarrollar aplicaciones web y aplicaciones nativas.

La segunda es, en esencia, la primera plantilla, que se ha ampliado debido a mi sistema para organizar la navegación a través de la aplicación.

Aquí hay una aplicación de demostración de papu basada en las consideraciones anteriores. Está lleno de errores y callejones sin salida, pero puede ensamblarlo usted mismo, ejecutarlo en un navegador y en un dispositivo móvil, y en la práctica tener una idea de cómo funciona todo.

Resumen


La comunidad de desarrolladores de React, por supuesto, necesita una biblioteca universal para organizar la navegación de aplicaciones, ya que esto simplificará el desarrollo de proyectos como el que mencionamos. Sería muy bueno si la biblioteca React Navigation funcionara en la web (de hecho, esta característica ya está disponible , pero trabajar con ella no está exenta de dificultades).

Estimados lectores! ¿Aprovechas React para crear aplicaciones universales?

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


All Articles