React Native Navigation y pantalla de login

Implementación de una pantalla de login en una aplicación de React Native

Image for post
Image for post

Hoy en este artículo os quiero hablar de cómo podéis crear una pantalla de login en una aplicación desarrollada con React Native cuando empleéis como librería de navegación React Native Navigation de Wix:

La verdad es que en general estoy muy contento con esta librería y todos los casos de uso que se me han ido presentando los resuelve perfectamente, por lo que la suelo escoger frente a otras alternativas como la famosa React Navigation, de la que hablaré en un siguiente artículo.

Así que sin más preámbulos veamos cómo poner una pantalla de login delante de vuestra aplicación para posteriormente pasar a un diseño de tabs como suele ser habitual en iOS (y últimamente también en Android). Es decir:

Image for post
Image for post

Aviso que el diseño no va a ser lo más prioritario en este artículo como habréis comprobado. Y ahora sí, ¡vamos a ello!

0. Requisitos

Lo primero de todo será crear un proyecto de React Native mediante el comando react-native :

react-native init AwesomeProject

Nota. A fecha de julio de 2019 recomiendo emplear la versión 0.59.* ya que la versión 0.60 me ha dado problemas de compatibilidad con React Native Navigation.

A continuación, instalaremos y configuraremos la librería React Native Navigation siguiendo su tutorial por lo que, si habéis completado todos los pasos que en él se describen, deberíais tener un archivo index.js con el siguiente aspecto:

Image for post
Image for post

Llegados a este punto os recomiendo que corráis en el simulador la aplicación para aseguraros de que todo ha ido bien y podamos seguir avanzando.

1. ¿Cómo funciona React Native Navigation?

Por si acaso no estáis familiarizados con esta librería os diré la forma en que funciona React Native Navigation. Si atendéis al código anterior, veréis que en su tercera línea estoy invocando el método registerComponent de la clase Navigation lo cual permite asociar un identificador (en este caso navigation.playground.WelcomeScreen) al componente que le pasemos como segundo argumento. Por tanto, cada pantalla de nuestra aplicación tendremos que registrarla de este modo con el fin de que posteriormente podamos navegar entre ellas.

Por otra parte, en la línea 6 estamos invocando el método setRoot una vez que la aplicación ha sido lanzada. Con este método podremos definir el layout de navegación que queremos que emplee nuestra aplicación, por ejemplo, una única pantalla como sería el caso, una barra inferior con pestañas o una pila de navegación a través de la cual podemos avanzar o retroceder. Todo esto está documentado en su correspondiente sección de la documentación. De momento, lo que estaríamos haciendo en el index.js es tener una aplicación con un único componente sin ningún tipo de navegación posible.

Sin embargo, a lo que queremos llegar es:

  • Si el usuario todavía no ha iniciado sesión, mostrarle una pantalla de login
  • Si el usuario ha iniciado sesión, mostrarle una vista con una barra inferior con dos pestañas como en la segunda imagen de la introducción de este artículo.

Así que veamos paso a paso cómo lograrlo.

2. Definiendo y registrando pantallas

Ahora que ya sabemos como funciona React Native Navigation (aunque sea por encima) lo siguiente que haremos será definir dos pantallas / componentes:

  • El primero será un componente con la lógica de inicio de sesión
  • El segundo será un componente con texto básico (nos puede servir el que nos da por defecto react-native cuando creamos la aplicación) que emplearemos en ambas pestañas una vez que el usuario ha iniciado sesión.

Componente para iniciar sesión

El componente para iniciar sesión será muy básico:

Image for post
Image for post

Básicamente tengo en el estado el email y contraseña del usuario junto con un campo error en el caso de que falle el inicio de sesión y un bool para marcar que el formulario se está enviando.

En el método onSubmit recojo los valores del email y contraseña almacenados en el estado y hago una llamada a mi API (línea 23). En la línea 24 he añadido el comentario // más tarde porque posteriormente añadiremos ahí la lógica para realizar la transición al layout de barra inferior con pestañas.

Finalmente, tengo un componente llamado LoginForm que renderea el formulario de inicio de sesión:

Image for post
Image for post

Componente para las pestañas

Por otra parte y como ya os adelantaba antes, el componente que emplearemos para mostrarse en las dos pestañas que componen la navegación de un usuario que ha iniciado sesión lo he cogido tal cual del archivo App.js por lo que no creo que sea necesario mostrar su código.

Registrando los componentes

Una vez que ya tenemos ambos componentes creados, lo que haremos será registrarlos en React Native Navigation para que pueda trabajar con ellos. Yo lo que generalmente hago cuando trabajo con esta librería es tener una carpeta llamada src/screens en donde meto los componentes que representan pantallas de la aplicación (en nuestro caso tendría src/screens/LoginFormScreen y src/screen/LoggedScreen ) y además un archivo denominado registerScreens.js con el siguiente contenido:

Image for post
Image for post

Es decir, una función que se encarga de llamar al método Navigation.registerComponent por cada pantalla de la aplicación, asociando cada componente con su correspondiente identificador (el cual podéis escoger al gusto).

Finalmente esta función la importo en el archivo index.js de modo que presentará el siguiente aspecto:

Image for post
Image for post

Como veis, ahora en la línea 10 he cambiado el identificador antiguo por el de la pantalla de login de modo que si ahora corréis la aplicación lo que veréis si todo ha ido bien es algo similar a esto:

Image for post
Image for post

3. Cambiando el layout de React Native Navigation

Ahora ya lo que nos queda es conseguir realizar el cambio de ese layout (en el que sólo se ve el componente de iniciar sesión) a un layout con pestañas inferiores cuando el usuario inicia sesión.

Como supongo que posteriormente guardaréis esa información bien mediante redux-persist bien mediante asyncStorage también es interesante arrancar la aplicación con el layout correcto en función de si el usuario ya había iniciado sesión previamente o no.

Para ello crearemos un archivo llamado src/services/setNavigationRoot.js con el contenido siguiente:

Image for post
Image for post

De verdad, es más sencillo de lo que parece:

  • En la línea 5 estoy recurriendo a una función que recupera el usuario del AsyncStorage (aunque evidentemente podéis emplear cualquier método que queráis para almacenar el usuario en el dispositivo y así persistir dicha información).
  • En la línea 7 compruebo si existía el usuario y en ese caso creo siguiendo la documentación de React Native Navigation un layout con dos pestañas. En la propiedad name de ambas pestañas estoy empleando el identificador app.logged que es el asociado al componente LoggedScreen , por lo que en ambas se mostrará el mismo componente. Además, estoy envolviendo ambos componentes en un stack (líneas 12 y 33) para que posteriormente pueda navegar a otras pantallas desde el componente inicial de la pestaña.
  • En el caso de que el usuario no hubiese iniciado sesión previamente, creo un layout con un stack cuyo único children será mi componente LogginFormScreen (cuyo identificador, que es el que uso para realizar la asociación es app.loginForm ).

Finalmente en la línea 74 invoco el método Navigation.setRoot para establecer la raíz con el layout que hayamos generado.

Hecho esto, modificaremos nuestro archivo index.js para que emplee esta función:

Image for post
Image for post

Si todo ha ido bien, vuestra aplicación debería seguir funcionando sin problema por lo que ya sólo queda modificar el root layout cuando el usuario inicia sesión.

Cómo modificar el root layout tras el inicio de sesión

Recordad que el objetivo es conseguir realizar la transición siguiente una vez que el usuario se ha autenticado en la aplicación:

Image for post
Image for post

Por tanto, volveremos a nuestro componente LoginFormScreen y en la línea 24 donde dejé el comentario //más tarde añadiremos lo siguiente:

Image for post
Image for post

Es decir, hacemos la llamada a la API, si todo va bien invoco mi método setUser que guarda el resultado mediante AsyncStorage (este método he considerado que no era necesario mostrarlo ya que no es el objetivo del artículo pero si lo necesitáis pedídmelo en los comentarios) y finalmente invocamos a la función setNavigationRoot que habíamos creado previamente. Puesto que ya tendremos almacenado el usuario en el AsyncStorage ahora la condición de la línea 7 del archivo setNavigationRoot.js será true y obtendremos como resultado la transición a nuestra navegación por pestañas.

4. Consideraciones adicionales

Como os comentaba anteriormente, he prescindido de incluir el código que no he considerado relevante para el artículo pero podéis pedírmelo a través de los comentarios.

Por otra parte en este artículo he prescindido de algunas buenas prácticas por no hacerlo excesivamente lento. Por ejemplo, os animo a tener un archivo extra llamado src/screens/ScreensIdentifiers.js donde tengáis todas los identificadores de las pantallas como constantes:

export const LOGIN_SCREEN = 'app.loginForm';export const LOGGED_SCREEN = 'app.logged';

De cara a no tener que escribir directamente los strings cuando registréis los componentes o creéis el layout.

Espero que este artículo os haya servido y que si os habéis quedado con alguna duda me la dejéis en los comentarios. Estaré encantado de responderla!

¿Quieres recibir más artículos como este?

Suscríbete a nuestra newsletter:

Written by

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store