Taller React Native-H
Taller React Native-H
Taller React Native-H
REACT NATIVE
Las plataformas nativas, como Android o iOS, permiten desarrollar aplicaciones utilizando
los lenguajes de programación y las herramientas específicas de cada plataforma. Esto
significa que se debe escribir código separado para cada plataforma, lo que puede requerir
más tiempo y recursos.
Por otro lado, los sistemas multiplataforma, como React Native y Flutter, permiten
desarrollar aplicaciones utilizando un único código base que se puede ejecutar en múltiples
plataformas. Estas plataformas utilizan frameworks y bibliotecas que traducen el código a
un lenguaje nativo para cada plataforma.
Además de las funcionalidades proporcionadas por las plataformas nativas, las aplicaciones
móviles a menudo hacen uso de bibliotecas de terceros para agregar características
adicionales. Estas bibliotecas pueden incluir funcionalidades como la integración con
servicios en la nube, análisis de datos, autenticación de usuarios, entre otros.
En resumen, al crear una aplicación, se debe considerar si se utilizará una plataforma nativa
o una plataforma multiplataforma, si se requerirá almacenamiento de datos local utilizando
SQLite1 y si se utilizarán bibliotecas de terceros para agregar funcionalidades adicionales.
A continuación, se presenta una tabla comparativa de las herramientas más utilizadas para
proyectos móviles (tomado de
https://rua.ua.es/dspace/bitstream/10045/136523/1/Estudio_y_benchmarking_de_tecnologi
as_de_creacion_de_Gonzalez_Torres_Ricardo.pdf)
1
SQLite es una biblioteca de base de datos relacional que se utiliza comúnmente en
aplicaciones móviles para almacenar y administrar datos localmente en el dispositivo del
usuario. Proporciona una forma eficiente y confiable de almacenar datos estructurados.
REACT NATIVE
React Native es una opción popular para el desarrollo de aplicaciones móviles debido a
varias razones:
Eficiencia de desarrollo: React Native permite escribir código una vez y ejecutarlo en
múltiples plataformas, como iOS y Android. Esto reduce el tiempo y los recursos
necesarios para desarrollar y mantener aplicaciones móviles.
Comunidad activa: React Native cuenta con una gran comunidad de desarrolladores que
comparten conocimientos, recursos y bibliotecas de código abierto. Esto facilita el
aprendizaje y la resolución de problemas durante el desarrollo de aplicaciones.
Integración con tecnologías existentes: React Native se puede integrar fácilmente con
código nativo existente, lo que permite aprovechar las funcionalidades y características
específicas de cada plataforma.
:
i. Mas adelante, ingresar en el emulador, su correo Gmail
7. Instalar Expo CLI, Una interfaz de línea de comandos que permite montar un
servidor para correr el proyecto en localmente, construir proyectos sencillos y
publicarlo. En Google buscar “expo install” y el enlace “Como instalar Expo (React
Native) – gists – GitHub”
a. Copiar el comando “npm install -g expo-cli exp” y ejecutarlo en Power
Shell, como administrador.
1. En la terminal de VSC
a. Cambiar a la carpeta de proyecto: “cd AppReactNAtive“
b. ejecutar “npm run Android” , se lanzara el emulador.
Buscar en Google “React native components”, en “Core Components” para tener una guía
al construir el código.
Imagen de Fondo
Formulario de ingreso
Agregue una vista interna, con sus estilos. Modifique el código así:
</View>
);
}
<View style={styles.logoContainer}>
<Image
source={require('./assets/logo.png')}
style={styles.logoImage}
/>
<Text style={styles.logoText}>FOOD APP</Text>
</View>
logoContainer:{
position: 'absolute',
alignSelf: 'center',
top: '15%',
},
logoImage: {
width: 100,
height: 100,
},
logoText: {
color: 'white',
textAlign: 'center',
fontSize: 20,
marginTop: 10,
fontWeight: 'bold',
}
<View style={styles.form}>
<Text style={styles.formText}>INGRESAR</Text>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('./assets/email.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Correo electrónico'
keyboardType='email-address'
/>
</View>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('./assets/password.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Contraseña'
keyboardType='default'
secureTextEntry={true}
/>
</View>
<View style={styles.formRegister}>
<Text>¿No tienes cuenta?</Text>
<Text style={styles.formRegisterText}>Regístrate</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'black',
},
imageBackground: {
width: '100%',
height: '100%',
opacity: 0.7,
bottom: '30%',
},
form: {
width: '100%',
height: '40%',
backgroundColor: 'white',
position: 'absolute',
bottom: 0,
borderTopLeftRadius: 40,
borderTopRightRadius: 40,
padding: 30,
},
formText: {
fontWeight: 'bold',
fontSize: 16,
},
formIcon: {
width: 25,
height: 25,
marginTop: 5,
},
formInput: {
flexDirection: 'row',
marginTop: 30,
},
formTextInput: {
flex: 1,
borderBottomWidth: 1,
borderBottomColor: '#AAAAAA',
marginLeft: 15,
},
formRegister: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 30,
},
formRegisterText: {
fontStyle: 'italic',
color: 'orange',
borderBottomWidth: 1,
borderBottomColor: 'orange',
fontWeight: 'bold',
marginLeft: 10,
},
logoContainer: {
position: 'absolute',
alignSelf: 'center',
top: '15%',
},
logoImage: {
width: 100,
height: 100,
},
logoText: {
color: 'white',
textAlign: 'center',
fontSize: 20,
marginTop: 10,
fontWeight: 'bold',
},
});
>
<Text>ENTRAR</Text>
</TouchableOpacity>
)
}
</View>
>
<Text style={styles.textButton} >ENTRAR</Text>
</TouchableOpacity>
)
}
interface Props {
text: string;
onPress: () => void,
Verifique el funcionamiento del código anterior, ¡debe aparecer una pequeña ventana
emergente con el mensaje “HOLA!”
Dentro de la carpeta “src” crear una carpeta “theme” y dentro de esta el archivo
“AppTheme.tsx”
En este archivo teclear “rafc” para generar el snippet, cambiar por HomeScreen:
Cortar todo el código, desde el return con la pantalla inicial, desde “App.tsx” en
“home.tsx”, quedará así:
return (
<View style={styles.container}>
<Image
source={require('./assets/chef.jpg')}
style={styles.imageBackground}
/>
<View style={styles.logoContainer}>
<Image
source={require('./assets/logo.png')}
style={styles.logoImage}
/>
<Text style={styles.logoText}>FOOD APP</Text>
</View>
<View style={styles.form}>
<Text style={styles.formText}>INGRESAR</Text>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('./assets/email.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Correo electrónico'
keyboardType='email-address'
/>
</View>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('./assets/password.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Contraseña'
keyboardType='default'
secureTextEntry={true}
/>
</View>
<View style={styles.formRegister}>
<Text>¿No tienes cuenta?</Text>
<Text style={styles.formRegisterText}>Regístrate</Text>
</View>
</View>
</View>
);
}
},
formInput: {
flexDirection: 'row',
marginTop: 30,
},
formTextInput: {
flex: 1,
borderBottomWidth: 1,
borderBottomColor: '#AAAAAA',
marginLeft: 15,
},
formRegister: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 30,
},
formRegisterText: {
fontStyle: 'italic',
color: 'orange',
borderBottomWidth: 1,
borderBottomColor: 'orange',
fontWeight: 'bold',
marginLeft: 10,
},
logoContainer: {
position: 'absolute',
alignSelf: 'center',
top: '15%',
},
logoImage: {
width: 100,
height: 100,
},
logoText: {
color: 'white',
textAlign: 'center',
fontSize: 20,
marginTop: 10,
fontWeight: 'bold',
},
});
<Stack.Screen
name="HomeScreen"
component={HomeScreen}
/>
{ /*<Stack.Screen name="Profile" component={ProfileScreen} /> */}
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
Al compilar y ejecutar expo, se genera un error debido a las rutas de las imágenes, cambiar
así:
<Image
source={require('../../../assets/chef.jpg')}
style={styles.imageBackground}
/>
<View style={styles.logoContainer}>
<Image
source={require('../../../assets/logo.png')}
style={styles.logoImage}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
const navigation =
useNavigation<StackNavigationProp<RootStackParamList>>();
return (
Debe ejecutar en la terminal el siguiente comando para instalar el complemento “npm i
@react-navigation/stack”. Debe verse registrado en el archivo “package.json”.
return (
<View style={styles.container}>
<Image
source={require('../../../assets/chef.jpg')}
style={styles.imageBackground}
/>
<View style={styles.logoContainer}>
<Image
source={require('../../../assets/user_image.png')}
style={styles.logoImage}
/>
<Text style={styles.logoText}>SELECCIONA UNA IMAGEN</Text>
</View>
<View style={styles.form}>
<Text style={styles.formText}>REGISTRARSE</Text>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('../../../assets/user.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Nombres'
keyboardType='default'
/>
</View>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('../../../assets/my_user.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Apellidos'
keyboardType='default'
/>
</View>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('../../../assets/email.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Correo electrónico'
keyboardType='email-address'
/>
</View>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('../../../assets/phone.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Teléfono'
keyboardType='numeric'
/>
</View>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('../../../assets/password.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Contraseña'
keyboardType='default'
secureTextEntry={true}
/>
</View>
<View style={styles.formInput}>
<Image style={styles.formIcon}
source={require('../../../assets/confirm_password.png')}
/>
<TextInput
style={styles.formTextInput}
placeholder='Confirmar Contraseña'
keyboardType='default'
secureTextEntry={true}
/>
</View>
<View style={{ marginTop: 30 }}>
<RoundedButton text='CONFIRMAR' onPress={() =>
ToastAndroid.show('HOLA!', ToastAndroid.SHORT)} />
</View>
</View>
</View>
);
}
imageBackground: {
width: '100%',
height: '100%',
opacity: 0.7,
bottom: '30%',
},
form: {
width: '100%',
height: '70%',
backgroundColor: 'white',
position: 'absolute',
bottom: 0,
borderTopLeftRadius: 40,
borderTopRightRadius: 40,
padding: 30,
},
formText: {
fontWeight: 'bold',
fontSize: 16,
},
formIcon: {
width: 25,
height: 25,
marginTop: 5,
},
formInput: {
flexDirection: 'row',
marginTop: 25,
},
formTextInput: {
flex: 1,
borderBottomWidth: 1,
borderBottomColor: '#AAAAAA',
marginLeft: 15,
},
formRegister: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 30,
},
formRegisterText: {
fontStyle: 'italic',
color: 'orange',
borderBottomWidth: 1,
borderBottomColor: 'orange',
fontWeight: 'bold',
marginLeft: 10,
},
logoContainer: {
position: 'absolute',
alignSelf: 'center',
top: '5%',
alignItems: 'center',
},
logoImage: {
width: 100,
height: 100,
},
logoText: {
color: 'white',
textAlign: 'center',
fontSize: 20,
marginTop: 10,
fontWeight: 'bold',
},
});
Agregar constantes para cada campo del formulario, antes de la constante navigation:
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const navigation =
useNavigation<StackNavigationProp<RootStackParamList>>();
Relacionar las constantes con los inputs del formulario y controlar el evento:
<TextInput
style={styles.formTextInput}
placeholder='Correo electrónico'
keyboardType='email-address'
value={email}
onChangeText={ text => setEmail(text)}
/>
<TextInput
style={styles.formTextInput}
placeholder='Contraseña'
keyboardType='default'
secureTextEntry={true}
value={password}
onChangeText={ text => setPassword(text)}
/>
Para probar, cambiar el evento del botón para enviar los valores a la terminal:
SI todo va bien, en la terminal se mostrarán los valores digitados, al dar clic en el botón:
ORGANIZANDO EL CÓDIGO CON EL PATRÓN DE DISEÑO MVVM
Capa de Presentación
Contendrá todo lo relacionado con las vistas.
Crear una carpeta “Presentation” dentro de “src”.
Arrastrar a ella las carpetas “components”, “theme” y “views”, debe detener la
aplicación y cerrar VSC para que permita el cambio manual.
Se deben cambiar las rutas de los recursos, agregando “../”, en “App.tsx” a
import { HomeScreen } from './src/Presentation/views/home/home';
import { RegisterScreen } from
'./src/Presentation/views/register/Register';
Capa de Dominio
Dentro de “src” cree una carpeta “Domain”.
Capa de Datos
Dentro de “src” cree una carpeta “Data”.
Pasar los userState a cada una de las carpetas, creando un archivo ‘viewModel.tsx’ en cada
carpeta de ‘views’, cortar los userState de “Home.tsx” y en ‘viewModel.tsx’ construir un
objeto así:
return {
...values,
onChange
}
}
Nota: los tres puntos en el código realizan una “desestructuración”, es decir, separa los
elementos de la estructura original.
En “Home.tsx” modificar:
return (
<TextInput
style={styles.formTextInput}
placeholder='Contraseña'
keyboardType='default'
secureTextEntry={true}
value={password}
onChangeText={ text => onChange('email', text)}
/>
<TextInput
style={styles.formTextInput}
placeholder='Contraseña'
keyboardType='default'
secureTextEntry={true}
value={password}
onChangeText={ text => onChange('password', text)}
/>
Hay que confirmar que todo esté correcto, ingresando los datos y dando clic en el botón. El
código funciona lo mismo que anteriormente, pero está organizado de una manera más
profesional.
interface Props {
image: any;
placeholder: string;
value: string;
keyboardType: KeyboardType,
secureTextEntry?: boolean,
property: string,
onChangeText: (property: string, value: any) => void,
}
},
formInput: {
flexDirection: 'row',
marginTop: 30,
},
formTextInput: {
flex: 1,
borderBottomWidth: 1,
borderBottomColor: '#AAAAAA',
marginLeft: 15,
}
})
return (
<View style={styles.container}>
<Image
source={require('../../../../assets/chef.jpg')}
style={styles.imageBackground}
/>
<View style={styles.logoContainer}>
<Image
source={require('../../../../assets/logo.png')}
style={styles.logoImage}
/>
<Text style={styles.logoText}>FOOD APP</Text>
</View>
<View style={styles.form}>
<Text style={styles.formText}>INGRESAR</Text>
<CustomTextInput
image= {require('../../../../assets/email.png')}
placeholder='Correo electrónico'
keyboardType='email-address'
property='email'
onChangeText={onChange}
value={email}
/>
<CustomTextInput
image= {require('../../../../assets/password.png')}
placeholder='Contraseña'
keyboardType='default'
property='password'
onChangeText={onChange}
value={password}
secureTextEntry={true}
/>
<View style={styles.formRegister}>
<Text>¿No tienes cuenta?</Text>
<TouchableOpacity onPress={() =>
navigation.navigate('RegisterScreen')}>
<Text
style={styles.formRegisterText}>Regístrate</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
formRegisterText: {
fontStyle: 'italic',
color: 'orange',
borderBottomWidth: 1,
borderBottomColor: 'orange',
fontWeight: 'bold',
marginLeft: 10,
},
logoContainer: {
position: 'absolute',
alignSelf: 'center',
top: '15%',
},
logoImage: {
width: 100,
height: 100,
},
logoText: {
color: 'white',
textAlign: 'center',
fontSize: 20,
marginTop: 10,
fontWeight: 'bold',
},
});
return {
...values,
onChange,
register
}
}
Observe que se modifica el evento para mostrar en la terminal los valores ingresados.
Modificar el archivo “register.tsx” así:
return (
<View style={styles.container}>
<Image
source={require('../../../../assets/chef.jpg')}
style={styles.imageBackground}
/>
<View style={styles.logoContainer}>
<Image
source={require('../../../../assets/user_image.png')}
style={styles.logoImage}
/>
<Text style={styles.logoText}>SELECCIONA UNA IMAGEN</Text>
</View>
<View style={styles.form}>
<Text style={styles.formText}>REGISTRARSE</Text>
<CustomTextInput
image={require('../../../../assets/user.png')}
placeholder='Nombres'
keyboardType='default'
property='name'
onChangeText={onChange}
value={name}
/>
<CustomTextInput
image={require('../../../../assets/my_user.png')}
placeholder='Apellidos'
keyboardType='default'
property='lastname'
onChangeText={onChange}
value={lastname}
/>
<CustomTextInput
image={require('../../../../assets/email.png')}
placeholder='Correo electrónico'
keyboardType='email-address'
property='email'
onChangeText={onChange}
value={email}
/>
<CustomTextInput
image={require('../../../../assets/phone.png')}
placeholder='Teléfono'
keyboardType='numeric'
property='phone'
onChangeText={onChange}
value={phone}
/>
<CustomTextInput
image={require('../../../../assets/password.png')}
placeholder='Contraseña'
keyboardType='default'
property='password'
onChangeText={onChange}
value={password}
secureTextEntry={true}
/>
<CustomTextInput
image={require('../../../../assets/confirm_password.png')}
placeholder='Confirmar Contraseña'
keyboardType='default'
property='confirmPassword'
onChangeText={onChange}
value={confirmPassword}
secureTextEntry={true}
/>
</View>
</View>
);
}
En la carpeta “home” crear un archivo “Styles.tsx”, cortar y pegar los estilos dentro de
“home.tsx” y modificar así:
import { StyleSheet } from "react-native";
formRegisterText: {
fontStyle: 'italic',
color: 'orange',
borderBottomWidth: 1,
borderBottomColor: 'orange',
fontWeight: 'bold',
marginLeft: 10,
},
logoContainer: {
position: 'absolute',
alignSelf: 'center',
top: '15%',
},
logoImage: {
width: 100,
height: 100,
},
logoText: {
color: 'white',
textAlign: 'center',
fontSize: 20,
marginTop: 10,
fontWeight: 'bold',
},
});
return (
<View style={styles.container}>
<Image
source={require('../../../../assets/chef.jpg')}
style={styles.imageBackground}
/>
<View style={styles.logoContainer}>
<Image
source={require('../../../../assets/logo.png')}
style={styles.logoImage}
/>
<Text style={styles.logoText}>FOOD APP</Text>
</View>
<View style={styles.form}>
<Text style={styles.formText}>INGRESAR</Text>
<CustomTextInput
image= {require('../../../../assets/email.png')}
placeholder='Correo electrónico'
keyboardType='email-address'
property='email'
onChangeText={onChange}
value={email}
/>
<CustomTextInput
image= {require('../../../../assets/password.png')}
placeholder='Contraseña'
keyboardType='default'
property='password'
onChangeText={onChange}
value={password}
secureTextEntry={true}
/>
<View style={styles.formRegister}>
<Text>¿No tienes cuenta?</Text>
<TouchableOpacity onPress={() =>
navigation.navigate('RegisterScreen')}>
<Text
style={styles.formRegisterText}>Regístrate</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}