Índice
A menudo se necesitan dos conjuntos diferentes de pilas de navegación para la autenticación previa y posterior del usuario. Por lo general, para ver más contenido, debes estar autenticado de alguna manera. Veamos cómo montar y desmontar la pila de navegación según una condición cumplida en React Native.
En este artículo, veremos el montaje y desmontaje de rutas de navegación en React Native. Un comportamiento esperado de su aplicación es que una vez que se cumple la condición de autenticación, un nuevo conjunto de rutas de navegación esté disponible solo para los usuarios que hayan iniciado sesión, mientras que las otras pantallas que se mostraban antes de la autenticación se eliminan y no se pueden regresar a menos que se el usuario cierra sesión en la aplicación.
Para mayor seguridad en su aplicación, las rutas protegidas le brindan una manera de mostrar solo cierta información/contenido de su aplicación a usuarios específicos, al tiempo que restringen el acceso de personas no autorizadas.
Trabajaremos con Expo para este proyecto porque nos ayudará a centrarnos en el problema en cuestión en lugar de preocuparnos por muchas configuraciones. Se pueden seguir exactamente los mismos pasos de este artículo para una aplicación React Native básica.
Necesita cierta familiaridad con JavaScript y React Native para seguir este tutorial. Aquí hay algunas cosas importantes con las que ya debería estar familiarizado:
- Componentes personalizados en React Native (cómo crear componentes, recibir, pasar y usar accesorios en un componente). Leer más .
- Reaccionar navegación. Leer más .
- Navegador de pila en React Native. Leer más .
- Conocimientos básicos de los componentes de React Native Core (
View/
,,Text/
etc.). Leer más . - Reaccionar nativo
AsyncStorage
. Leer más . - API de contexto. Leer más .
Configuración del proyecto y autenticación básica
Si es nuevo en el uso de expo y no sabe cómo instalarlo, visite la documentación oficial . Una vez que se complete la instalación, continúe para inicializar un nuevo proyecto React Native con expo desde nuestro símbolo del sistema:
expo init navigation-project
Se le presentarán algunas opciones para elegir cómo desea que sea la configuración base:
En nuestro caso, seleccionemos la primera opción para configurar nuestro proyecto como un documento en blanco. Ahora, espere hasta que se complete la instalación de las dependencias de JavaScript.
Una vez que nuestra aplicación esté configurada, podemos cambiar nuestro directorio a nuestro nuevo directorio de proyecto y abrirlo en su editor de código favorito. Necesitamos instalar la biblioteca que usaremos AsyncStorage
y nuestras bibliotecas de navegación. Dentro del directorio de su carpeta en su terminal, pegue el comando anterior y elija una plantilla ( blank
funcionaría) para instalar las dependencias de nuestro proyecto.
Veamos para qué sirve cada una de estas dependencias:
- @react-native-community/async-storage
Al igual que localStorage en la web, es una API React Native para conservar datos en un dispositivo en pares clave-valor. - @react-native-community/masked-view, reaccionar-native-screens, reaccionar-native-gesture-handle
Estas dependencias son utilidades principales que utilizan la mayoría de los navegadores para crear la estructura de navegación en la aplicación. (Lea más en Introducción a la navegación de React Native ). - @react-navigation/native
Esta es la dependencia para la navegación de React Native. - @react-navigation/stack
Esta es la dependencia para la navegación por la pila en React Native.
npm install @react-native-community/async-storage @react-native-community/masked-view @react-navigation/native @react-navigation/stack react-native-screens react-native-gesture-handle
Para iniciar la aplicación, utilícela expo start
desde el directorio de aplicaciones en su terminal. Una vez iniciada la aplicación, puede usar la aplicación expo desde su teléfono móvil para escanear el código de barras y ver la aplicación, o si tiene un emulador de Android/simulador de IOS, puede abrir la aplicación a través de ellos desde la herramienta de desarrollo de expo que se abre en su navegador cuando inicia una aplicación de exposición. Para los ejemplos de imágenes de este artículo, usaremos Genymotions para ver nuestro resultado. Así es como se verá nuestro resultado final en Genymotions:
Estructuras de carpetas
Creemos nuestra estructura de carpetas desde el principio para que nos resulte más fácil trabajar con ella a medida que avanzamos:
Primero necesitamos dos carpetas:
- contexto
Esta carpeta contendrá el contexto de toda nuestra aplicación, ya que trabajaremos con Context API para la gestión del estado global. - vistas
Esta carpeta contendrá tanto la carpeta de navegación como las vistas de diferentes pantallas.
Continúe y cree las dos carpetas en el directorio de su proyecto.
Dentro de la carpeta de contexto, cree una carpeta llamada authContext y cree dos archivos dentro de la carpeta authContext :
- AuthContext.js ,
- AuthState.js .
Necesitaremos estos archivos cuando comencemos a trabajar con Context API.
Ahora vaya a la carpeta de vistas que creamos y cree dos carpetas más dentro de ella, a saber:
- navegación ,
- pantallas .
Ahora bien, aún no hemos terminado, dentro de la carpeta de pantallas , crea estas dos carpetas más:
- postAuthScreens ,
- pantallas de autenticación previa .
Si siguió la configuración de carpetas correctamente, así es como debería verse su estructura de carpetas en este momento:
Creando nuestra primera pantalla
Ahora creemos nuestra primera pantalla y llamémosla bienvenidoScreen.js dentro de la carpeta preAuthScreens .
preAuthScreens bienvenidoScreen.js
Aquí está el contenido de nuestro archivo bienvenidoScreen.js :
import React from 'react';import { View, Text, Button, StyleSheet, TextInput } from 'react-native';const WelcomeScreen = () = { const onUserAuthentication = () = { console.log("User authentication button clicked") } return ( View style={styles.container} Text style={styles.header}Welcome to our App!/Text View TextInput style={styles.inputs} placeholder="Enter your email here.." / TextInput style={styles.inputs} secureTextEntry={true} placeholder="Enter your password here.." /Button onPress={onUserAuthentication} / /View /View )}const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, header: { fontSize: 25, fontWeight: 'bold', marginBottom: 30 }, inputs: { width: 300, height: 40, marginBottom: 10, borderWidth: 1, }})export default WelcomeScreen
Esto es lo que hicimos en el bloque de código anterior:
Primero, importamos las cosas que necesitamos de la biblioteca React Native, a saber View
, Text
, Button
, TextInput
. A continuación, creamos nuestro componente funcional WelcomeScreen
.
Notarás que importamos el StyleSheet
de React Native y lo usamos para definir estilos para nuestro encabezado y también nuestro TextInput /
.
Por último, exportamos el WelcomeScreen
componente al final del código.
Ahora que hemos terminado con esto, hagamos que este componente funcione como se esperaba usando el useState
enlace para almacenar los valores de las entradas y actualizar sus estados cada vez que ocurra un cambio en los campos de entrada. También importaremos el useCallback
gancho de React, ya que lo necesitaremos más adelante para realizar una función.
Primero, mientras todavía estamos en el WelcomeScreen
componente, necesitamos importar el useState
y useCallback
desde React.
import React, { useState, useCallback } from 'react';
Ahora, dentro del WelcomeScreen
componente funcional, creemos los dos estados para el correo electrónico y la contraseña respectivamente:
...const WelcomeScreen = () = { const [email, setEmail] = useState('') const [password, setPassword] = useState('') return ( ... )}...
A continuación, debemos modificar nuestros TextInput /
campos para que obtengan su valor de sus respectivos estados y actualicen su estado cuando se actualice el valor de la entrada:
import React, { useState, useCallback } from 'react';import { View, Text, Button, StyleSheet, TextInput } from 'react-native';const WelcomeScreen = () = { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const onInputChange = (value, setState) = { setState(value); } return ( View ... View TextInput style={styles.inputs} placeholder="Enter your email here.." value={email} onChangeText={(value) = onInputChange(value, setEmail)} / TextInput style={styles.inputs} secureTextEntry={true} placeholder="Enter your password here.." value={password} onChangeText={(value) = onInputChange(value, setPassword)} / ... /View /View )}...
En el código anterior, esto es lo que hicimos:
- Hicimos que
value
cada una de las entradas de texto señalara sus respectivos estados. - Agregamos el
onChangeText
controlador a nuestras entradas de texto. Esto se activa cada vez que se ingresa o elimina un nuevo valor de los campos de entrada. - Llamamos a nuestra
onInputChange
función que acepta dos argumentos:- La corriente
value
la suministra elonChangeText
manipulador. - El definidor del estado que debe actualizarse (para el primer campo de entrada pasamos
setEmail
y para el segundo pasamossetPassword
. - Finalmente, escribimos nuestra
onInputChange
función, y nuestra función solo hace una cosa: actualiza los estados respectivos con el nuevo valor.
- La corriente
Lo siguiente en lo que debemos trabajar es en la onUserAuthentication()
función que se llama cada vez que se hace clic en el botón para enviar el formulario.
Idealmente, el usuario ya debe haber creado una cuenta y el inicio de sesión implicará algún tipo de lógica de backend para verificar que el usuario existe y luego asignarle un token. En nuestro caso, dado que no utilizamos ningún backend, crearemos un objeto que contenga los detalles de inicio de sesión del usuario correctos y luego solo autenticaremos a un usuario cuando los valores que ingrese coincidan con nuestros valores fijos del objeto de inicio de sesión que email
crearemos password
.
Aquí está el código que necesitamos para hacer esto:
...const correctAuthenticationDetails = { email: '[email protected]', password: 'password'}const WelcomeScreen = () = { ... // This function gets called when the `AUTHENTICATE` button is clicked const onUserAuthentication = () = { if ( email !== correctAuthenticationDetails.email || password !== correctAuthenticationDetails.password ) { alert('The email or password is incorrect') return } // In here, we will handle what happens if the login details are // correct } ... return ( ... )}...
Una de las primeras cosas que notará en el código anterior es que definimos correctAuthenticationDetails
(que es un objeto que contiene los detalles de inicio de sesión correctos que esperamos que proporcione el usuario) fuera del WelcomeScreen()
componente funcional.
A continuación, escribimos el contenido de la onUserAuthentication()
función y utilizamos una declaración condicional para verificar si email
o password
mantenido en los estados respectivos no coincide con el que proporcionamos en nuestro objeto.
Si desea ver lo que hemos hecho hasta ahora, importe el componente WelcomeScreen a su App.js de esta manera:
Abra el archivo App.js y coloque esto, reemplace el código completo con esto:
import { StatusBar } from 'expo-status-bar';import React from 'react';import { View } from 'react-native';import WelcomeScreen from './views/screens/preAuthScreens/welcomeScreen';export default function App() { return ( View StatusBar / WelcomeScreen / /View );}
Si observa detenidamente el código anterior, verá que lo que hicimos fue importar el componente WelcomeScreen y luego lo usamos en la App()
función.
Así es como se ve el resultado de nuestro WelcomeScreen
aspecto:
Ahora que hemos terminado de crear el componente WelcomeScreen , avancemos y comencemos a trabajar con Context API para administrar nuestro estado global. Que dia se celebra hoy
¿Por qué la API de contexto?
Al usar Context API, no necesitamos instalar ninguna biblioteca adicional en ReactJS, es menos estresante de configurar y es una de las formas más populares de manejar el estado global en ReactJS. Para una gestión estatal ligera, es una buena opción.
Creando nuestro contexto
Si recuerdas, creamos una carpeta de contexto anteriormente y creamos una subcarpeta dentro de ella llamada authContext .
Ahora naveguemos hasta el archivo AuthContext.js en la carpeta authContext y creemos nuestro contexto:
contexto authContext AuthContext.js
import React, { createContext } from 'react';const AuthContext = createContext();export default AuthContext;
El AuthContext
que acabamos de crear contiene el loading
valor estatal y los userToken
valores estatales. Actualmente, en lo que createContext
declaramos en el bloque de código anterior, no inicializamos ningún valor predeterminado aquí, por lo que nuestro contexto actualmente es undefined
. Un valor de ejemplo del contexto de autenticación podría ser{loading: false, userToken: 'abcd}
El archivo AuthState.js contiene nuestra lógica de API de contexto y sus valores de estado. Las funciones escritas aquí se pueden llamar desde cualquier lugar de nuestra aplicación y cuando actualizan los valores en el estado, también se actualizan globalmente.
Primero, incluyamos todas las importaciones que necesitaremos en este archivo:
contexto AuthContext AuthState.js
import React, { useState } from 'react';import AuthContext from './AuthContext';import AsyncStorage from '@react-native-community/async-storage';
Importamos el useState()
gancho de ReactJS para contener nuestros estados, importamos el archivo AuthContext que creamos anteriormente porque aquí es donde se inicializa nuestro contexto vacío para la autenticación y necesitaremos usarlo como verá más adelante mientras avanzamos, finalmente importar el AsyncStorage
paquete (similar a localStorage para la web).
AsyncStorage
es una API de React Native que le permite conservar datos sin conexión en el dispositivo en una aplicación de React Native.
...const AuthState = (props) = { const [userToken, setUserToken] = useState(null); const [isLoading, setIsLoading] = useState(true); const onAuthentication = async() = { const USER_TOKEN = "drix1123q2" await AsyncStorage.setItem('user-token', USER_TOKEN); setUserToken(USER_TOKEN); console.warn("user has been authenticated!") } return ( AuthContext.Provider value={{ onAuthentication, }} {props.children} /AuthContext.Provider )}export default AuthState;
En el bloque de código anterior, esto es lo que hicimos:
-
Declaramos dos estados para
userToken
yisLoading
. EluserToken
estado se usará para almacenar el token guardado enAsyncStorage
, mientras que elisLoading
estado se usará para rastrear el estado de carga (inicialmente está configurado entrue
). Descubriremos más sobre el uso de estos dos estados a medida que avancemos. -
A continuación, escribimos nuestra
onAuthentication()
función. Esta función es unaasync
función que se llama cuando se hace clic en el botón de inicio de sesión desde elwelcomeScreen.jsx
archivo. Esta función solo se llamará si el correo electrónico y la contraseña que el usuario proporcionó coinciden con el objeto de detalle de usuario correcto que proporcionamos. Por lo general, lo que sucede durante la autenticación es que se genera un token para el usuario después de que el usuario se autentica en el backend usando un paquete como JWT , y este token se envía al frontend. Como no vamos a entrar en todo eso en este tutorial, creamos un token estático y lo guardamos en una variable llamadaUSER_TOKEN
. -
A continuación, usamos la
await
palabra clave para configurar nuestro token de usuario en AsyncStorage con el nombreuser-token
. Elconsole.warn()
extracto solo sirve para comprobar que todo ha ido bien, puedes quitártelo cuando quieras. -
Finalmente, pasamos nuestra
onAuthenticated
función como un valor dentro de nuestraAuthContext.Provider
para que podamos acceder y llamar a la función desde cualquier lugar de nuestra aplicación.
pantallas preAuth bienvenidoScreen.js
Primero, importe useContext
desde ReactJS e importe AuthContext
desde el AuthContext.js
archivo.
import React, { useState, useContext } from 'react';import AuthContext from '../../../context/authContext/AuthContext'...
Ahora, dentro del welcomeScreen()
componente funcional, usemos el contexto que hemos creado:
...const WelcomeScreen = () = { const { onAuthentication } = useContext(AuthContext) const onUserAuthentication = () = { if ( email !== correctAuthenticationDetails.email || password !== correctAuthenticationDetails.password ) { alert('The email or password is incorrect') return } onAuthentication() } return ( ... )}...
En el bloque de código anterior, desestructuramos la onAuthentication
función de nuestro AuthContext
y luego la llamamos dentro de nuestra onUserAuthentication()
función y eliminamos la console.log()
declaración que estaba allí antes.
En este momento, esto arrojará un error porque todavía no tenemos acceso al archivo AuthContext
. Para usar en AuthContext
cualquier lugar de su aplicación, debemos empaquetar el archivo de nivel superior en nuestra aplicación con AuthState
(en nuestro caso, es el archivo App.js ).
Vaya al archivo App.js y reemplace el código allí con esto:
import React from 'react';import WelcomeScreen from './views/screens/preAuthScreens/welcomeScreen';import AuthState from './context/authContext/AuthState'export default function App() { return ( AuthState WelcomeScreen / /AuthState );}
Hemos llegado hasta aquí y hemos terminado con esta sección. Antes de pasar a la siguiente sección donde configuramos nuestra ruta, creemos una nueva pantalla. La pantalla que estamos a punto de crear será el archivo HomeScreen.js que se supone que aparecerá sólo después de una autenticación exitosa.
Vaya a: pantallas postAuth .
Cree un nuevo archivo llamado HomeScreen.js . Aquí está el código para el archivo HomeScreen.js :
pantallas postAuth HomeScreen.js
import React from 'react';import { View, Text, Button, StyleSheet } from 'react-native';const HomeScreen = () = { const onLogout = () = { console.warn("Logout button cliked") } return ( View style={styles.container} TextNow you're authenticated! Welcome!/Text Button onPress={onLogout} / /View )}const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', },})export default HomeScreen
Por ahora, el botón de cerrar sesión tiene una console.log()
declaración ficticia. Posteriormente crearemos la funcionalidad de cierre de sesión y la pasaremos a la pantalla desde nuestro contexto.
Configurando nuestras rutas
Necesitamos crear tres (3) archivos dentro de nuestra carpeta de navegación:
- postAuthNavigator.js ,
- preAuthNavigator.js ,
- AppNavigator.js .
Una vez que haya creado estos tres archivos, navegue hasta el archivo preAuthNaviagtor.js que acaba de crear y escriba esto:
navegación preAuthNavigator.js
import React from "react";import { createStackNavigator } from "@react-navigation/stack";import WelcomeScreen from "../screens/preAuthScreens/welcomeScreen";const PreAuthNavigator = () = { const { Navigator, Screen } = createStackNavigator(); return ( Navigator initialRouteName="Welcome" Screen name="Welcome" component={WelcomeScreen} / /Navigator )}export default PreAuthNavigator;
En el archivo anterior, esto es lo que hicimos:
- Importamos el
createStackNavigator
desde el@react-navigation/stack
cual estamos usando para nuestra navegación de pila. ProporcionacreateStackNavigator
una forma para que su aplicación realice la transición entre pantallas donde cada pantalla nueva se coloca en la parte superior de una pila. De forma predeterminada, el navegador de pila está configurado para tener la apariencia familiar de iOS y Android: las nuevas pantallas se deslizan desde la derecha en iOS y aparecen gradualmente desde abajo en Android. Haga clic aquí si desea obtener más información sobre el navegador de pila en React Native . - Nos desestructuramos
Navigator
yScreen
delcreateStackNavigator()
. - En nuestra declaración de devolución, creamos nuestra navegación con
Navigator/
y creamos nuestra pantalla conScreen/
. Esto significa que si tuviéramos varias pantallas a las que se pudiera acceder antes de la autenticación,Screen/
aquí tendremos varias etiquetas que las representen. - Finalmente, exportamos nuestro
PreAuthNavigator
componente.
Hagamos algo similar para el postAuthNavigator.js
archivo.
navegación postAuthNavigator.js
import React from "react";import { createStackNavigator } from "@react-navigation/stack";import HomeScreen from "../screens/postAuthScreens/HomeScreen";const PostAuthNavigator = () = { const { Navigator, Screen} = createStackNavigator(); return ( Navigator initialRouteName="Home" Screen name="Home" component={HomeScreen} / /Navigator )}export default PostAuthNavigator;
Como vemos en el código anterior, la única diferencia entre preAuthNavigator.js y postAuthNavigator.js es la pantalla que se representa. Mientras que el primero toma el WelcomeScreen
, postAuthNavigator.js toma el HomeScreen
.
Para crear nuestro AppNavigator.js necesitamos crear algunas cosas.
Dado que AppNavigator.js es donde cambiaremos y verificaremos qué ruta estará disponible para el acceso del usuario, necesitamos varias pantallas para que esto funcione correctamente, describamos las cosas que debemos crear primero:
- TransitionScreen.js
Mientras la aplicación decide qué navegación va a montar, queremos que aparezca una pantalla de transición. Normalmente, la pantalla de transición será una rueda de carga o cualquier otra animación personalizada elegida para la aplicación, pero en nuestro caso, usaremos unaText/
etiqueta básica para mostrarloading…
. checkAuthenticationStatus()
Esta función es a la que llamaremos para verificar el estado de autenticación que determinará qué pila de navegación se montará. Crearemos esta función en nuestro contexto y la usaremos en Appnavigator.js .
Ahora, sigamos adelante y creemos nuestro archivo TransitionScreen.js .
pantallas TransitionScreen.js
import React from 'react';import { Text, View } from 'react-native';const TransitionScreen = () = { return ( View TextLoading.../Text /View )}export default TransitionScreen
Nuestra pantalla de transición es solo una pantalla simple que muestra texto de carga. Veremos dónde utilizar esto a medida que avancemos en este artículo.
A continuación, vayamos a nuestro AuthState.js y escribamos nuestro checkAuthenticationStatus()
:
contexto authContext AuthState.js
import React, { useState, useEffect } from 'react';import AuthContext from './AuthContext';import AsyncStorage from '@react-native-community/async-storage';const AuthState = (props) = { const [userToken, setUserToken] = useState(null); const [isLoading, setIsLoading] = useState(true); ... useEffect(() = { checkAuthenticationStatus() }, []) const checkAuthenticationStatus = async () = { try { const returnedToken = await AsyncStorage.getItem('user-toke n'); setUserToken(returnedToken); console.warn('User token set to the state value) } catch(err){ console.warn(`Here's the error that occured while retrievin g token: ${err}`) } setIsLoading(false) } const onAuthentication = async() = { ... } return ( AuthContext.Provider value={{ onAuthentication, userToken, isLoading, }} {props.children} /AuthContext.Provider )}export default AuthState;
En el bloque de código anterior, escribimos la función checkAuthenticationStatus()
. En nuestra función, esto es lo que estamos haciendo:
- Usamos la
await
palabra clave para obtener nuestro tokenAsyncStorage
. ConAsyncStorage
, si no se proporciona ningún token, devuelvenull
. NuestrouserToken
estado inicial también está configuradonull
. - Usamos
setUserToken
para establecer nuestro valor devueltoAsyncStorage
como nuestro nuevouserToken
. Si el valor devuelto esnull
, significa nuestrosuserToken
restosnull
. - Después del
try{}…catch(){}
bloqueo, lo configuramosisLoading
en falso porque la función para verificar el estado de autenticación está completa. Necesitaremos el valor deisLoading
para saber si aún deberíamos mostrarloTransitionScreen
o no. Vale la pena considerar configurar un error si hay un error al recuperar el token para que podamos mostrarle al usuario un botón "Reintentar" o "Intentar de nuevo" cuando se encuentre el error. - Cada vez que
AuthState
se monta queremos verificar el estado de autenticación, por lo que usamos eluseEffect()
gancho ReactJS para hacer esto. Llamamos a nuestracheckAuthenticationStatus()
función dentro deluseEffect()
gancho y establecemos el valor deisLoading
cuandofalse
esté listo. - Finalmente, agr
Tal vez te puede interesar:
- ¿Deberían abrirse los enlaces en ventanas nuevas?
- 24 excelentes tutoriales de AJAX
- 70 técnicas nuevas y útiles de AJAX y JavaScript
- Más de 45 excelentes recursos y repositorios de fragmentos de código
Manejo del montaje y desmontaje de rutas de navegación en React Native
Estructuras de carpetasCreando nuestra primera pantalla¿Por qué la API de contexto?Creando nuestro contextoTal vez te puede interesar:Anuncie en la revista S
programar
es
https://pseint.es/static/images/programar-manejo-del-montaje-y-desmontaje-de-rutas-de-navegacion-en-react-native-1116-0.jpg
2024-05-24
Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente