Notas de Freelancer: Desarrollo de la primera aplicación nativa de React

El autor del material, cuya traducción publicamos, lanzó recientemente su primera aplicación móvil escrita en React Native. Dio la casualidad de que esta aplicación también fue su primer proyecto, que creó como programador independiente. Aquí hablará sobre lo que tuvo que enfrentar durante el trabajo, desde la inicialización del proyecto hasta su publicación en la App Store y Google Play.



¿Por qué elegí freelance?


En mayo pasado, presenté un maravilloso proyecto independiente. En ese momento, yo era un desarrollador de pila completa en una startup en Estocolmo. Este fue mi primer trabajo de programación, llegué allí hace apenas un año ( aquí hablo sobre esto con más detalle).

El verano se acercaba rápidamente, el ritmo del trabajo, antes de esa locura, día tras día se estaba volviendo más tranquilo. Una vez hubo una semana en la que, en orden de prioridad, tuve que lidiar con el soporte técnico. Tuve que lidiar con algunos errores, estaba un poco aburrido, el trabajo no me agradó.

Fue cuando estaba tan triste que mi padre me informó de sus intenciones de crear una aplicación móvil para los clientes de su empresa. Aunque sabía que estaba muy ocupado en el trabajo, y no esperaba que le diera todo mi tiempo para implementar su idea, aún así me preguntó si me gustaría convertirme en algún tipo de consultor en este nuevo proyecto. Entonces sentí que tenía hambre de un trabajo mental interesante y, por lo tanto, respondí su pregunta positivamente. Aunque inicialmente no planeé esto, desde el consultor, como resultado, me convertí en un desarrollador líder de aplicaciones.

Aquí puede preguntarse por qué alguien podría incluso intentar hacer desarrollo móvil después de no haber trabajado como desarrollador web profesional durante un año. ¿No sería más sabio continuar ganando experiencia en un nicho elegido, crecer profesionalmente y crear un currículum impresionante?

Estoy completamente de acuerdo en que esto sería mucho más razonable. Pero soy un desesperado "trabajador de múltiples estaciones" que decidió hace varios años tomar decisiones profesionales basadas no en una determinada estrategia, sino en mis propias preferencias. Decidí hacer lo que me da alegría. En otras palabras, mi currículum vitae ahora parece tal que difícilmente puede ser llevado a un estado aún más errático.

Por supuesto, hacer lo que te gusta y seguir una estrategia de carrera no son necesariamente fenómenos mutuamente excluyentes. De hecho, me gustó tanto mi trabajo anterior como el empleador. Dio la casualidad de que me encontré con otro proyecto, cuyo anhelo resultó ser más fuerte que el deseo de hacer lo que estaba haciendo antes.

¿Qué hizo que este proyecto fuera tan atractivo para mí? ¿Qué lo hizo más interesante que trabajar en un producto de rápido desarrollo que utilizan miles de empresas, como parte de un equipo formado por las mejores personas que he conocido? Esta pregunta puede responderse de esta manera: esta es la libertad, este es el desafío que me ha dado la necesidad de resolver un problema difícil, y este es el deseo de autodesarrollo.

¿Por qué se decidió utilizar React Native?


Cuando me uní al proyecto, mi cliente ya había recibido varias ofertas de agencias digitales locales. Incluso antes de considerar la posibilidad de desarrollar la aplicación de forma independiente, me pidieron de manera amigable que evaluara estas propuestas. Cuando los miré, simplemente me sorprendió su baja calidad.

Una de las agencias envió un resumen del diseño de la aplicación, que, además de parecer descuidado, no correspondía con la identidad corporativa reflejada en el sitio del cliente. Otro sugirió precios altísimos, tanto para el desarrollo como para el apoyo a proyectos. El tercero, al parecer, envió la propuesta, sin siquiera haber estudiado realmente los requisitos del cliente. Todas las agencias que presentaron las propuestas tenían una cosa en común: iban a crear una aplicación utilizando el marco híbrido de Cordova.

Pero eso no es todo. Aunque Cordova es una herramienta completamente gratuita y de código abierto, una de las agencias incluso trató de ocultar información sobre qué tecnología específica utiliza. En cambio, los representantes de la agencia hablaron de una plataforma de desarrollo de aplicaciones móviles "interna" creada internamente. Parece que estábamos hablando de un pequeño complemento sobre Cordova, hecho solo para asegurar firmemente los derechos exclusivos de esta agencia para el servicio de la aplicación y hacer que la posible transición futura del cliente a otro desarrollador sea difícil y costosa. En general, las propuestas en cuestión no fueron particularmente impresionantes.

Cabe señalar que no tengo nada en contra de los marcos híbridos. Constantemente uso aplicaciones que se basan en ellos. Esto, por ejemplo, Gmail, Slack, Atom, Figma. Sin embargo, escuché sobre React Native durante algún tiempo, sobre cómo esta biblioteca te permite crear aplicaciones móviles multiplataforma usando JavaScript que no eran híbridos.

¿Y ahora que? ¿Es necesario, de alguna manera difícil, admitir iOS y Android cuando se desarrollan aplicaciones JavaScript nativas? Esta pregunta surgió debido al hecho de que cuando estaba interesado en tales aplicaciones, resultó que las aplicaciones de iOS se escribieron usando Objective-C o Swift, y Java o Kotlin se usaron para desarrollar aplicaciones de Android.

Por supuesto, no hay trucos especiales aquí. Entonces tenía una pregunta más. ¿Cómo pueden las aplicaciones React Native llamarse aplicaciones nativas reales? Si responde esta pregunta en pocas palabras, resulta que todo está en la API. Me tomó más tiempo entender esto de lo que me gustaría reconocer, pero la forma en que las aplicaciones React Native, llamadas native, funcionan con plataformas móviles, no consiste en lanzar código JavaScript o compilar dicho código en código nativo La cuestión es que estas aplicaciones ejecutan solicitudes de API que muestran componentes nativos utilizando Objective-C en iPhone y Java en Android.

Si desea obtener una comprensión más profunda de los conceptos básicos de React Native, le recomiendo esta respuesta a Quora, esta es una presentación con React Conf, y este material, que informa sobre el lanzamiento de React Native.

Aunque en ese momento no sabía qué estaba sucediendo exactamente en las entrañas de las aplicaciones React Native, sabía que el trabajo de tales aplicaciones se reducía a la ejecución de código nativo. Este fue mi argumento principal en contra de elegir una de las soluciones basadas en Córdoba ofrecidas por las agencias. Pensé que si una empresa necesita una aplicación móvil, esta aplicación debería ser nativa. Si alguien necesita una aplicación basada en HTML / CSS / JS, entonces sería mejor gastar el dinero simplemente para mejorar las capacidades móviles de su aplicación web.

Cuando compartí este razonamiento con un cliente, él me hizo una pregunta sobre si conozco a alguien que pueda crear dicha aplicación. Le respondí que no lo sabía. Luego me preguntaron si podía hacerlo yo mismo. "No puedo", respondí. Sin embargo, para ese momento ya estaba interesado en todo esto y simplemente no podía evitar experimentar con React Native, tomando las especificaciones de la aplicación como la base de mis experimentos.

Antes de darme cuenta de esto, pude crear la base para la aplicación. Como resultado, solo unas pocas semanas después de esa conversación, el cliente y yo acordamos que desarrollaría la aplicación para él.

Especificaciones de aplicación


Antes de profundizar en los detalles técnicos, quiero hablar un poco sobre qué tipo de aplicación estamos tratando.

El cliente para el que se desarrolla la aplicación es una empresa en Estocolmo, que se dedica a la gestión de coworking, oficinas colectivas. En otras palabras, estamos hablando de espacios de oficinas que pueden ser alquilados por varias compañías. En este momento, mi cliente tiene alrededor de 10 oficinas existentes en las que aproximadamente 400 empresas con 1.400 empleados alquilan espacio. Estos son los inquilinos de las oficinas y son el público objetivo de la aplicación.


Área de recreación en uno de los coworking.

Después de discutir la futura aplicación con el gerente del proyecto, logré averiguar algunos requisitos para el proyecto:

  • La capacidad de iniciar sesión, cerrar sesión y restablecer la contraseña. Tenga en cuenta que todas las cuentas de usuario son creadas por administradores y la aplicación no admite el registro en el sistema. Por lo tanto, si decide descargar esta aplicación, no podrá trabajar con ella.
  • Ver y editar el perfil del usuario: nombre, dirección de correo electrónico, contraseña, avatar.
  • Soporte para notificaciones push.
  • La sección Inicio, con la que el usuario puede familiarizarse con las noticias de la empresa en su conjunto y, en particular, con las noticias sobre el coworking alquilado por la empresa.
  • Sección de comunidad, con la cual el usuario puede ver información sobre varios coworking, contactar a sus gerentes y ver qué compañías están involucradas en cierto coworking.
  • Sección de conferencias, con la que puede reservar salas de reuniones y gestionar reservas.
  • Selección de sección, en la que el usuario puede encontrar descuentos y ofertas exclusivas.
  • Primero debe crear una versión de iOS, luego agregar compatibilidad con Android.
  • Aplicación basada en web para el administrador, que le permite administrar la información que se muestra en la aplicación React Native. Aunque aquí hablaré principalmente sobre el desarrollo front-end, creo que sería apropiado mencionar que la parte del servidor de la aplicación para el administrador se basa en Ruby on Rails, Postgres y Heroku.

Puede notar que este proyecto tiene requisitos bastante modestos. Tal vez, algo en este espíritu puede llamarse un buen ejemplo de la primera aplicación que alguien va a desarrollar utilizando un nuevo conjunto de tecnologías. Si está interesado en echar un vistazo a lo que terminé (y de paso decidiendo si pasar el tiempo leyendo la historia sobre cómo sucedió exactamente todo esto), aquí hay una descripción general de la primera versión de la aplicación.


Primera versión de la aplicación.

¿Todavía leyendo? Genial, entonces sigamos adelante.

Aprendiendo de los mejores


Imagina que prometiste a tus amigos que les construirían una casa. Pero no sabes cómo hacerlo. Realmente ni siquiera sabes por dónde empezar. ¿Qué se debe hacer primero en tal situación? La respuesta es obvia: encuentre a alguien que pueda construir casas y aprender de él.

Hablando estrictamente, esto es exactamente lo que intenté hacer. Y tuve mucha suerte de encontrar exactamente lo que necesitas. Entonces, después de solo unas pocas horas de búsqueda de materiales de capacitación de React Native, encontré en YouTube un video curso de Harvard React Native de 13 partes. Cada conferencia que duró 90-120 minutos se dedicó a un tema separado. Como resultado, me enfrenté a unas 23 horas de materiales de capacitación de alta calidad.

Habiendo encontrado este curso, inmediatamente, como obsesivo, me puse a estudiar. Como resultado, después de varias semanas de clases en las que podía pasar tardes y fines de semana, terminé este curso y creé una buena base para la aplicación.

Ahora puedo decir que ese curso, sin duda, es el mejor que logré encontrar. Las clases concisas y bien preparadas, por supuesto, desempeñaron un papel muy positivo en la escuela, pero no puedo dejar de notar la habilidad del maestro. Describiría el estilo de conducir estas clases con las siguientes palabras: velocidad, practicidad extrema, enfoque. Sin agua, sin bromas irrelevantes o historias de la vida. A diferencia de lo que tu humilde servidor escribe aquí ...

De una forma u otra, había la sensación de que había tanta información útil incluida en cada clase que tomaría el doble de tiempo presentarla a muchos otros maestros. En otras palabras, este curso es muy similar al conocido Harvard CS50.

Como resultado, si desea encontrar un punto de apoyo para su primera aplicación React Native, definitivamente le recomiendo este curso. Aunque aquí debe tenerse en cuenta una característica. Ese curso utiliza el kit de herramientas Expo . Esta es una excelente herramienta que es adecuada para la mayoría de las aplicaciones simples, que adquiere todo tipo de sutilezas con respecto al trabajo con plataformas móviles. Pero si usted, como yo, desea crear la base para un proyecto que, más temprano que tarde, puede convertirse en una aplicación bastante grande y compleja, y que, al mismo tiempo, desea total libertad de acción, probablemente sea mejor inicializar el proyecto mediante Reaccionar nativo.

El segundo "recurso de capacitación" que pude usar fueron mis colegas. Afortunadamente, la compañía donde trabajé también comenzó a desarrollar el proyecto React Native. Aunque yo mismo no participé en este proyecto, aprendí mucho, solo hablé con aquellos que trabajaron en este proyecto y analizaron su código.

Ahora que hemos discutido todo lo relacionado con el desarrollo de aplicaciones React Native, es hora de pasar a problemas técnicos.

Entorno de desarrollo


Después de usar un equipo del formulario react-native init MyApp , creé la base de la aplicación, una de las primeras tareas que me enfrenté fue el desarrollo de un nuevo entorno de desarrollo.

Si llegó al entorno React Native desde el desarrollo web habitual, entonces debe tenerse en cuenta que aquí le parecerá mucho familiar. Para mí, esto significaba que seguía usando Atom como editor de código, iTerm como terminal y GitUp como interfaz para trabajar con git. (Si los fanáticos de Vim están leyendo esto ahora, sugiero que todos no estén convencidos). Pero, además de las herramientas anteriores, necesitaba algo más para desarrollar aplicaciones React Native.

Por ejemplo, necesitaba acostumbrarme al emulador de iOS. Si bien la ejecución mediante la línea de comando del comando react-native run-ios parece engañosamente simple, al comienzo del trabajo una simple llamada a este comando no fue suficiente para que el emulador funcione normalmente. Dado que se agregaban nuevos paquetes npm al proyecto casi a diario (y más tarde, bastantes módulos nativos de CocoaPod), yo, mucho más cerca de lo que me gustaría, me vi obligado a familiarizarme con el desagradable ritual de borrar recursos de Watchman y caché de Haste, eliminando la carpeta node_modules reinstalar módulos y restablecer el caché de Metro Bundler. Afortunadamente, todas estas tareas se pueden resolver con el siguiente comando:

 watchman watch-del-all && rm -rf tmp/haste-map-react-native-packager && rm -rf node_modules && yarn && npm start --reset-cache 

En 9 de cada 10 casos, tal "baile con pandereta" permitió que el emulador volviera a la vida. A veces, sin embargo, incluso esto no era suficiente. Luego tuve que profundizar en la descripción de los mensajes de error en GitHub y leer las discusiones sobre StackOverflow.

La raíz de algunos otros problemas fue el hecho de que durante mucho tiempo pensé que para resolver algunos problemas, era necesario ejecutar Xcode. Y créanme, se esforzarán por permanecer en esta casa de terror IDE el menor tiempo posible.

Una historia similar fue con el lanzamiento del emulador con una cierta versión del iPhone. Si alguien me hubiera dicho antes que el comando a continuación resuelve este problema directamente desde la línea de comando, entonces podría haber vivido un poco más fácil en mis primeros meses de desarrollo de React.

 react-native run-ios --simulator='iPhone X' 

Otros ejemplos de las dificultades de acostumbrarse al nuevo entorno de desarrollo incluyen el proceso de tres pasos de preparación de la versión de lanzamiento de la aplicación (para su colocación en la App Store o en algún entorno de integración continua, como Visual Studio App Center o Firebase) y el proceso de transición de la versión de lanzamiento a la versión, destinado a la depuración (al modo de desarrollo). Quizás a muchos les resulte obvio que los cambios necesarios en el proyecto pueden realizarse utilizando cualquier editor de texto. En cualquier caso, este es solo un ejemplo de un par de pequeñas cosas que tuvieron un gran impacto inesperado en mi flujo de trabajo cuando trabajaba en modo de desarrollo.

Y finalmente, me llevó un tiempo acostumbrarme a la necesidad de cambiar constantemente entre las diversas aplicaciones de macOS necesarias para resolver las tareas que yo, al desarrollar aplicaciones web, solía resolver usando Chrome solo.

Para ver lo que el código JavaScript está escribiendo en la consola y analizar, con fines de depuración, la salida HTML / CSS, recurrí al React Native Debugger . Para monitorear el estado de la aplicación, las acciones enviadas, las solicitudes de API y las respuestas recibidas, utilicé Reactotron . Aunque encontré ambas aplicaciones extremadamente útiles, no pude evitar pensar en mi flujo de trabajo habitual utilizado para crear aplicaciones Ember.js, cuando pude resolver todas estas tareas en el mismo entorno en el que se ejecutaban mis aplicaciones (usando el complemento Ember Inspector para Chrome).

La navegación


Organizar la navegación / enrutamiento parece ser una tarea muy difícil para React Native. Durante la existencia de este marco, han aparecido muchas soluciones diferentes a este problema, pero todavía hay algo que podría llamarse un estándar universalmente reconocido. Decidí usar la biblioteca de navegación de reacción, mi elección estuvo influenciada principalmente por el hecho de que hablaron sobre esta biblioteca en el curso React Native que hice, así como por el hecho de que mis colegas la usaron.

Si invirtiera algo de tiempo en un estudio suficientemente profundo de este tema, podría descubrir lo siguiente:

  • El proyecto de navegación de reacción tiene aproximadamente 15,000 estrellas en GitHub y 86 problemas sin resolver. Está completamente basado en JavaScript y presenta la documentación más detallada entre las soluciones de navegación que he visto.
  • La biblioteca react-native-navigation obtuvo alrededor de 10,000 estrellas, resultó que tenía 162 problemas sin resolver. Sin embargo, usa no solo JavaScript. Para trabajar con él necesitas editar archivos nativos.
  • El repositorio de react-router posee aproximadamente 35,000 estrellas y una lista de 55 problemas pendientes en GitHub. Es cierto que estos indicadores no se pueden comparar directamente con los otros proyectos descritos aquí, ya que este repositorio incluye paquetes diseñados no solo para React Native, sino también para React.
  • El proyecto de navegación nativa tiene alrededor de 3.000 estrellas y 55 problemas no resueltos. Aquellos que van a estudiarlo y usarlo deben considerar que todavía está en beta, que usa no solo JavaScript y que es compatible con Airbnb (esta compañía decidió abandonar React Native )

Pero, incluso teniendo en cuenta lo anterior, probablemente hubiera elegido la navegación de reacción de todos modos, ya que no tuve tiempo para probar todas estas bibliotecas, como, por ejemplo, el autor de este informe. Y finalmente, como se dijo en este informe, la elección de una herramienta para organizar la navegación es una pregunta cuya solución no depende de cuál de estas herramientas puede llamarse la mejor, sino de cuál se adapta mejor a las necesidades de un proyecto en particular.

Después de trabajar con react-navigation durante aproximadamente 9 meses, debo decir que realmente no tengo nada de qué quejarme. Si compara esta biblioteca con la conocida biblioteca router.js utilizada en Ember.js , puedo decir que esto es algo completamente nuevo.

Fue realmente fácil para mí lidiar con los tres tipos principales de herramientas de navegación de navegación de reacción. Estos son StackNavigator , TabNavigator y DrawerNavigator . Fue mucho más difícil entender cómo combinar estas herramientas para crear el sistema de navegación de aplicaciones que necesitaba.

Por ejemplo, el hecho de que el componente DrawerNavigator debería ser el elemento raíz del sistema de navegación (un paso por encima del componente principal TabNavigation ) no me pareció evidente. Si es difícil de imaginar, así es como DrawerNavigator ve en acción (en una aplicación real, todo funciona mucho mejor).


DrawerNavigator de react-navigation en acción

Como puede ver, necesitaba abrir la barra de navegación lateral con un deslizamiento, en cualquier pantalla de aplicación.

Percibí la barra lateral como algo secundario en comparación con la barra de navegación principal ubicada en la parte inferior de la aplicación. Por lo tanto, me pareció que DrawerNavigator debería colocarse en el árbol de ruta (se muestra a continuación) ya sea debajo del BottomTabNavigator principal, o en el mismo nivel que este elemento.

Sin embargo, después de sufrir mucho, tratando de forzar la barra lateral en el lugar donde resultó ser inapropiado, me di cuenta de que, de acuerdo con las características de la navegación de reacción, DrawerNavigator debería colocarse un paso por encima del BottomTabNavigator , es decir, en raíz del árbol de navegación. Espero que este hallazgo mío ayude a uno de los lectores de este material a ahorrar tiempo que de lo contrario se gastaría leyendo documentación y materiales en GitHub.

Así es como se ve el árbol de navegación de la aplicación. Aquí, como elemento raíz, MainDraverNavigation utiliza MainDraverNavigation .


El árbol de navegación final de la primera versión de la aplicación.

Aquí puede preguntarse por qué, para las secciones Comunidad y Conferencia, necesita tanto StackNavigator como TabNavigator . ¿No puedes soltar la capa StackNavigator e ir directamente a TabNavigator ?

La TabNavigator es que necesitaba que cada uno de los dos elementos TabNavigator tuviera un título. Aquí están


TabNavigator, título

Aquí, nuevamente, mis conjeturas no coincidían con el dispositivo de navegación de reacción. Pensé que MaterialTopTabNavigator debería ser un componente de navegación completamente normal, así que decidí que debería haber alguna opción incorporada en su configuración que le permita establecer un título. Al final resultó que no había nada de eso, y es por eso que tuve que usar StackNavigator como una capa intermedia, agregando, como resultado, un nivel adicional de complejidad a la infraestructura de la aplicación y guiado por consideraciones bastante "cosméticas".

Esta falta de reacción de navegación, además, me causó problemas mucho más serios. En particular, consistían en la necesidad de organizar el plegado y la desaparición de la imagen del encabezado durante el desplazamiento del usuario a través de la lista de elementos organizados por FlatList . Dado que los títulos de las secciones Inicio y Selección se mostraban dentro del mismo StackNavigator que las listas de sus elementos, este problema no sería difícil de resolver simplemente dejando que el título se desplace junto con el resto de la lista.

Pero en el caso de las secciones Comunidad y Conferencia, no pude encontrar una manera de aplicar la misma solución, ya que los encabezados se muestran con los elementos StackNavigator y las listas se muestran con los elementos StackNavigator , un paso más arriba en el árbol de navegación. Como resultado, me negué a desplazar el título, lo que introdujo una heterogeneidad desagradable en la aplicación.


Desplazarse en TabNavigator y StackNavigator

Aunque el problema descrito con el título en el emulador que simula Iphone X no parece serio, en la pantalla pequeña el título puede ocupar aproximadamente el 20% del espacio disponible en la pantalla. Si alguien sabe cómo resolver este problema, avíseme.

El mismo problema con TabNavigator también se sintió en la sección Destino. Como se mostrará en la siguiente figura, a la derecha, quería colocar otro elemento TabNavigator en la pestaña Espacios TabNavigator para mostrar las tres pestañas superiores Información, Miembros y Contacto.

Al trabajar con TabNavigator era difícil colocar una presentación de diapositivas en la parte superior del elemento sin tener que complicar la decisión y no causar muchos problemas de navegación (principalmente relacionados con las opciones de navegación). Así que tuve que recurrir a un paquete JS llamado react-native-swiper para trabajar con estas tres pestañas. Cabe señalar que esta solución me convendría por completo si su aplicación no condujera a una animación abrupta de líneas que enfatizan los encabezados de las pestañas. En cualquier caso, consideré que esta desventaja era un pago justo por la oportunidad de evitar problemas con un sistema de navegación alternativo.


Compare TabNavigator de react-navigation con react-native-swiper (observe la diferencia en la animación de las líneas doradas debajo de los nombres de las pestañas)

Estas son las conclusiones que hice después de implementar el subsistema de navegación de aplicaciones:

  • Hay muchas soluciones bien documentadas para organizar la navegación en las aplicaciones React Native, entre las cuales elegí react-navigation. Se adapta mejor a mis necesidades.
  • La biblioteca react-navigation simplifica enormemente el inicio del trabajo en un proyecto si el desarrollador no sabe mucho sobre cómo funcionan los sistemas de navegación de las plataformas móviles.
  • La biblioteca de navegación de reacción tiene algunas características que no son intuitivas (al menos para un desarrollador web), pero no hay nada que no se pueda eludir, aunque no de la manera más eficiente.

Pantalla de bienvenida


Al iniciar una nueva aplicación en el emulador creada por medio del comando react-native init , recargándola constantemente a medida que realiza cambios, se da cuenta rápidamente de que la aplicación necesita una bonita pantalla de bienvenida (también se llaman "pantallas de bienvenida").

Aquí está bien escrito cómo hacer una pantalla de bienvenida, por lo que no repetiré las palabras del autor de este material. Solo hablaré sobre el problema que encontré y sobre el cual no hay nada en esta guía. Así es como se ve este problema:


La pantalla de inicio con un problema

Este problema aparece en casos raros en iOS, pero algunos usuarios de la aplicación probablemente lo encuentren. Descubrí este problema por primera vez cuando trabajaba en un lugar, donde no podía usar WiFi y conectaba mi computadora portátil a Internet 4G a través de un teléfono. Los usuarios de iPhone saben que cuando el teléfono distribuye Internet, su barra de estado se vuelve azul y aumenta. Esto "rompió" la imagen en mi pantalla de inicio cuando inicié la aplicación en el teléfono. El mismo problema surgió al llamar.

Como resultado, después de haber hurgado durante algún tiempo en el repositorio de pantalla de reacción nativa y no encontrar nada útil allí, decidí evitar este problema ocultando completamente la barra de estado mientras mostraba la pantalla de bienvenida.

Es muy simple: simplemente agregue la clave UIStatusBarHidden , asignándole el valor lógico true y luego, después de llamar a SplashScreen.hide() , establezca la propiedad hidden del componente React Native StatusBar en StatusBar .

Gestión del estado


Tengo la sensación de que durante los últimos dos años he estado escuchando todos los días sobre la prioridad del acuerdo sobre la configuración, el principio de la Convención sobre la configuración (CoC). Así fue en mi trabajo anterior. Y esto no es sorprendente, ya que allí, en el servidor, utilizamos Ruby on Rails y en el cliente, Ember.js, dos marcos, cuya esencia coincide con el principio de CoC lo mejor posible. Pensé que sabía lo que eso significaba, pero el proceso de explorar la gestión del estado en React Native me dio una nueva comprensión de este principio.

Aunque, en varias aplicaciones muy simples, experimenté con la biblioteca React influenciada por este principio, nunca creé algo lo suficientemente grande basado en ella que me permitiera apreciar las ventajas de usar contenedores de estado como Redux o MobX . La mayor parte de mi experiencia en la administración del estado de las aplicaciones JS es con Ember Data (este es el sistema integrado de Ember para administrar el estado y organizar el almacenamiento persistente de datos).

Dado que la biblioteca de Redux me pareció una de las mejores soluciones al problema de gestión del estado que había escuchado durante muchos años (y que se discutió en el curso React Native que cubrí), en general, no miré hacia sus competidores . Solo quería equipar mi aplicación con lo mejor de los sistemas de gestión de estado existentes y hacerlo sin demasiado esfuerzo.

En Ember, el 90% de la infraestructura de datos está en manos del programador listo para usar. No sospechaba que en mi proyecto actual todo sería exactamente lo contrario. Al final resultó que, no solo React, sino Redux, la biblioteca de administración de estado más popular, no da nada útil para mantener el estado global. Esta biblioteca es tan liviana que el programador tiene que asumir el 90% de las preocupaciones sobre trabajar con datos dentro de la aplicación para crear un sistema de administración de estado decente.

Después de que, un desarrollador mucho menos experimentado que ahora, descubrí, lo más difícil para mí fue acostumbrarme a la nueva funcionalidad y los principios de inmunidad. Después de soportar la cantidad sorprendentemente grande de trabajo que hay que hacer para simplemente descargar datos del servidor o enviarlos al servidor, todo esto se reunió en forma de 7 pasos bastante simples:

  1. Agregue tres constantes al archivo con constantes: SOME_ACTION_REQUEST , SOME_ACTION_FAILED , SOME_ACTION_SUCCEEDED .
  2. Añadir creador de acción al archivo de acción.
  3. Procese tres acciones en un reductor adecuado y, si es necesario, agregue un nuevo reductor al sistema e inclúyalo en el reductor raíz.
  4. Agregue trabajadores a una saga adecuada y, si es necesario, agregue una nueva saga al sistema e inclúyala en la saga raíz (utilizo la biblioteca redux-saga para procesar acciones asincrónicas).
  5. Agregue una función para manejar cualquier posible solicitud de API.
  6. Asigne los datos necesarios del estado a las propiedades en el componente React correspondiente.
  7. Envíe la acción SOME_ACTION_REQUEST del componente React correspondiente.

Redux y redux-saga, por supuesto, tienen características mucho más amplias, pero teniendo en cuenta lo que actualmente me interesa, los 7 pasos anteriores son lo que Redux es para mí.

Sesiones


Entonces, configuramos el entorno de desarrollo para las aplicaciones React Native, creamos un árbol de navegación, preparamos la infraestructura de administración del estado. ¿Qué será bueno hacer en el próximo paso del proyecto? Para mí, la creación de un sistema de autenticación de usuarios fue una respuesta completamente natural a esta pregunta. Así que ahora hablaremos de sesiones.

Si llegaste a la esfera React Native desde el desarrollo web, entonces lidiarás con sesiones sin mucha dificultad. Si incluso está un poco familiarizado con los conceptos en los que se basa el almacenamiento LocalStorage , solo necesita saber que cuando trabaje con React Native, el acceso a dicho almacenamiento debe reemplazarse por una llamada a AsyncStorage . Este es el nivel de abstracción que le permite almacenar datos en formato clave-valor entre sesiones. En otras palabras, aquí puede almacenar el token de autenticación generado en el servidor, transmitido al cliente después de que el usuario inicie sesión con éxito en el sistema.

Listas


Si hablamos de trabajar con listas, tengo la sensación de que en React Native este problema se resolvió bastante bien. En general, se puede observar que el desarrollador tiene tres posibilidades. Si funciona con listas estáticas, los datos presentados no cambian, entonces ScrollView probablemente tendrá suficiente.Si necesita trabajar con listas más largas, que, además, son dinámicas, entonces vale la pena mirar FlatList . Si estamos hablando de listas aún más grandes, que, además, se pueden dividir en secciones, entonces será útil recurrir a SectionList .

Yo, para listas dinámicas, uso exclusivamente FlatList. Y aunque yo, en un nivel intuitivo, como estas listas y la capacidad de configurarlas, cuando trabajé con ellas, tuve varios problemas. Ahora hablaré de ellos.

▍Dibuja la lista para actualizar su contenido


FlatList , refreshControl . , , , , . , React Native , . — RefreshControl . , .


RefreshControl

, , , refreshControl , RefreshControl , , . , , :

  • , , . , handleRefresh() .
  • , , « » ( ).

— .

, , , , . , , , GitHub.

, refreshControl onEndReached ( ) fetching . , - , false true , — , , 250 , RefreshControl , .

, setTimeout() fetching 350 . . , , setTimeout — , , handleRefresh() handleLoadMore()refreshing loadingMore . , , , , - .

, onRefresh refreshing refreshControl . , refreshControl , , , , .


, . — , , Load More , , , , .


FlatList. , , 2, onEndReached , 2-

, onEndReached . .

onEndReachedThreshold , FlatList , , onEndReached . .

100 , , 10 , 1, onEndReachedThreshold , , onEndReached , , 90-. 2, , 2- , — 80- , .

, , , , FlatList . , , , , handleLoadMore() , onEndReached , , — 10 .

, , loadingMore , , handleLoadMore() , , , !loadingMore . , , .


ListLoadingComponent FlatList , , ListHeaderComponent , ListEmptyComponent ListFooterComponent , , - , , , .

, render() .


, , , . , , .

, scrollToOffset FlatList , , . , . ref FlatList :

 <FlatList ref={(ref) => { this.newsListRef = ref; }} ... /> 

, . ScrollToOffset handleScrollToTop() , , , react-navigation, , :

 componentDidMount() { this.props.navigation.setParams({   scrollToTop: this.handleScrollToTop, }); } handleScrollToTop = () => { this.newsListRef.ScrollToOffset({   x: 0, y: 0, animated: true, }); }; 

, react-navigation 3 ref , BottomTabNavigator .


, , . , , 4G- ( , , 3G), , , , , .

, , , , , , , . . , , , , .

, , . 7 , image , , ( , ).


, , . react-native-image-picker , Cloudinary Carrierwawe Rails-.

, Node-API Cloudinary react-native-fetch-blob . , , , , , .

, , react-native-fetch-blob, . , react-native-fetch-blob , API JS FormData . , react-native-fetch-blob rn-fetch-blob , .


, React Native Image style , source resizeMode . , , - , , , .

, , , . , , , . . Avatar react-native-elements.

, Image . , - , .

, , . .


react-native-slideshow

react-native-slideshow , , . , , , , , , .


7 , , . , — , , . , - . .

, , -, , , , - ( — ), , , , Facebook . , .

, , React Native-. , . — react-native-loading-placeholder , , , . — react-native-linear-gradient , . , , , , , , , , .


react-native-loading-placeholder react-native-linear-gradient


— . , React Native Image . , - CachedImage react-native-cached-image .

npm- Image , , , CachedImage . Reactotron , , .

, , , . , , Cloudinary, 95% , , 4%. .

, . CachedImage activityIndicatorProps={{ animating: false }} , .



React Native - Picker . - , ( - ), JS-, . , react-native-picker-select , <select> iOS Android .

JS-, React Native- ( lodash , ), , , , . , , - . , .


react-native-calendars Wix. :

  • iOS , . , , , -, — .
  • React Native — DatePickerIOS DatePickerAndroid , , .
  • , , , Apple Google.

, . , , — .


react-native-calendars react-native-picker-select


— , .
SaaS-, . SOAP, API Conference. , , , , .

, , , 5 . - , JavaScript Date UTC, , . , , , , , - . « », — .

, , moment-js , React Native, timezone , :

 const timeSthlmAfterFive = moment().isAfter(moment.tz('17:00:00', 'HH:mm:ss', 'Europe/Stockholm'), 'second'); 


, , , . React Native -, , , , , , font-face CSS.

. , . , 10 -. react-native-vector-icons .

, ,


CI/CD, DevOps- -, .

( ) , - . , . GitHub- . , :

  • . , , .
  • , - , , .

. , , , , , , push-. , , , , .

Visual Studio App Center (VSAC). Chain React 2017 . , , , DevOps-, . , , , , push-, Codepush . -. , , , , iOS, Android. , - , , , , , - .


Visual Studio App Center ( )

« », — , . , (API — ). , , , , -, (, , ).

? Microsoft, , VSAC « ». , , Codepush ( React Native-) HockeyApp ( ), - . , «developers, developers, developers, developers» .

, VSAC , - Fastlane , BuddyBuild Firebase ? , , , VSAC , , , . , , ? , VSAC, , .

VSAC. , , , .

, , , VSAC Apple Developers (Apple, , , ). , , , .

, VSAC, , , CI/CD- .

Android


, iOS- , Android . Android Studio Android React Native Platform . , Platform.select() . - , , , Platform.OS .

, , Google Play , App Store. Por qué , App Store Apple.

Apple


, -, React Native, . , Apple. , , , , , .


Apple

, — « ». -, , iOS-, , , , .

— Apple. , , , . Dun & Bradstreet, Apple, . , , , Apple (, , Apple , — ).

, Apple , , — , -. . , — ?

, .

, , Apple Developer . .

. . provisioning-, iOS-, , Apple .p12 push-, dSym-. , , , .

Apple, 50% 24 , 90% — 48 . , , — , , Apple-.

, . «Metadata Rejected». , - . , 5 ( App Store Review Guidelines ), .

, , , — . , , , , , . , — , () .

iOS, . , , , . , , . . , , .

Resumen


, React Native- . React Native-. -. , : . .

, , , , . , , — , .

, - , . . , , , 8 . . .

, . , , - .

, , , 6-7 , . , , , :

  • , (iOS Android), , , .
  • JavaScript. , , Ember.js.
  • React.js, , React-, . , JS-/.
  • , Redux.
  • DevOps .
  • , .
  • UI/UX.
  • , , , , , , , , .

JS- , Flutter , NativeScript , Objective-C, Swift, Java Kotlin, React Native .

, -, , React Native , , , . , React Native — , . React Native .

Estimados lectores! ?

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


All Articles