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

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:

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:

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:

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:

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:

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:

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:

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 medianteasyncStorage
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:

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 identificadorapp.logged
que es el asociado al componenteLoggedScreen
, por lo que en ambas se mostrará el mismo componente. Además, estoy envolviendo ambos componentes en unstack
(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 únicochildren
será mi componenteLogginFormScreen
(cuyo identificador, que es el que uso para realizar la asociación esapp.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:

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:

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

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: