Expo es una colección de herramientas que facilitan la codificación de las aplicaciones nativas React. En este tutorial, te mostraré cómo puedes crear rápidamente las aplicaciones React Native usando Expo.
Con Expo, los desarrolladores pueden crear aplicaciones React Native sin las frustraciones que conlleva la instalación y configuración de dependencias de software como Android Studio, Xcode o todas las demás herramientas necesarias para desarrollar y ejecutar una aplicación React Native..
En este tutorial, te mostraré cómo crear un juego de memoria simple utilizando Expo. En el camino también aprenderás lo siguiente:
Expo es un marco para el rápido desarrollo de aplicaciones React Native. Es como Laravel o Symphony para desarrolladores de PHP, o Ruby on Rails para desarrolladores de Ruby. Expo proporciona una capa sobre las API nativas de React para que sean más fáciles de usar y administrar. También proporciona herramientas que facilitan el arranque y la prueba de las aplicaciones nativas React. Por último, proporciona componentes y servicios de UI que normalmente solo están disponibles cuando instala un componente React Native de terceros. Todos ellos están disponibles a través del SDK de Expo.
Antes de continuar, es importante conocer algunas de las limitaciones de Expo:
Incluso con estas limitaciones, es importante tener en cuenta que Expo es un marco completamente funcional con mucho soporte para las API de Android o iOS más utilizadas. Esto significa que lo tiene cubierto para la mayoría de las funcionalidades que las aplicaciones comúnmente necesitan. Por lo tanto, a menudo no es necesario mirar fuera de Expo para implementar la funcionalidad nativa.
La aplicación que vamos a crear es un juego de memoria. Es posible que esté familiarizado con este tipo de juego: el usuario tiene que encontrar pares coincidentes entregando las cartas de dos en dos. Así es como se ve la pantalla predeterminada:
Y así es como se ve una vez que se han abierto todas las parejas:
Una vez que hayan resuelto el juego, el usuario puede tocar en el Reiniciar botón para restablecer los elementos a su estado inicial. Esto les permite comenzar el juego de nuevo..
A diferencia de plain React Native, donde tiene que instalar y configurar Android Studio o Xcode y otras dependencias, con Expo solo hay unos pocos pasos a seguir para comenzar a desarrollar aplicaciones:
npm install exp --global
Una vez que haya instalado todas las dependencias, ahora puede generar una nueva aplicación Expo:
exp init MemoryGame
Una vez hecho esto, se creará una nueva carpeta llamada Juego de memoria. Navegue dentro de él y comience a ejecutar el servidor de desarrollo:
cd MemoryGame exp start
Alternativamente, también puede utilizar la Expo XDE. Esto le permite crear y ejecutar aplicaciones de Expo a través de una GUI. Puedes descargar el instalador desde el repositorio de Expo GitHub. Actualmente, solo es compatible con Windows y Mac. Así que si estás en Ubuntu o Linux es mejor seguir con la línea de comandos por ahora.
Una vez que el servidor de desarrollo se está ejecutando, ahora debería poder ver algo como esto:
Ese es el código QR que apunta a la vista previa en vivo del proyecto. Abra la aplicación cliente Expo en su teléfono y escanee el código con el escáner QR. En este punto, ahora debería poder ver la pantalla predeterminada. Cada vez que golpeas Control-S en cualquiera de los archivos del proyecto, la vista previa debería volver a cargarse automáticamente para reflejar los cambios.
Puede encontrar el código fuente completo del proyecto en su repositorio de GitHub. O si desea probar la aplicación, puede ver la demostración. Simplemente seleccione Código QR y escanéelo en su teléfono usando la aplicación de cliente Expo.
Ahora estamos listos para codificar la aplicación. Comencemos con algunos componentes de la interfaz de usuario antes de regresar e implementar el componente principal.
El encabezado se utiliza para mostrar el título de la aplicación. Crear un componentes carpeta. Dentro de ella, crea un Header.js archivo y añadir lo siguiente:
importar reaccionar desde 'reaccionar'; importar StyleSheet, Text, View desde 'react-native'; exportar la clase predeterminada Encabezado extiende React.Component render () return (); const styles = StyleSheet.create (header: flex: 1, flexDirection: 'column', alignSelf: 'stretch', paddingTop: 20, paddingBottom: 5, backgroundColor: '# f3f3f3', header_text: fontWeight: 'bold', fontSize: 17, textAlign: 'center'); Juego de memoria
Este es solo un componente básico de React Native, con algunos estilos para coincidir con la interfaz de usuario de nuestra aplicación.
El siguiente es el componente para mostrar la puntuación (componentes / Score.js):
importar reaccionar desde 'reaccionar'; importar StyleSheet, Text, View desde 'react-native'; exportar la clase predeterminada Puntaje extiende React.Component render () return (); estilos const = StyleSheet.create (score_container: flex: 1, alignItems: 'center', padding: 10, score: fontSize: 40, fontWeight: 'bold'); this.props.score
De nuevo, solo un componente de visualización simple con una vista de texto y algunos estilos básicos.
El componente de la tarjeta (componentes / Card.js) mostrará las tarjetas. Estas tarjetas utilizan iconos del conjunto de iconos de vectores de Expo. Esta es una de las características que salen de la caja cuando se usa Expo: incluye iconos de conjuntos de iconos como FontAwesome, Entypo e Ionicons.
En el código a continuación, puedes ver que solo estamos usando FontAwesome. Tiene el icono que queremos para mostrar el estado predeterminado de la tarjeta: un signo de interrogación. Como verá más adelante en el componente principal de la aplicación, también usaremos íconos de Entypo e Ionicons. La referencia a esas fuentes de iconos se pasará a este componente, por lo que no es necesario especificarlas aquí:
importar reaccionar desde 'reaccionar'; importar StyleSheet, Text, View, TouchableHighlight desde 'react-native'; importe FontAwesome desde '@ expo / vector-icons'; // usa FontAwesome de los iconos de vectores de la expo
Dentro de hacer()
Método, solo usamos la fuente y el icono pasados como accesorios si la tarjeta está abierta. De forma predeterminada, solo mostrará el icono de signo de interrogación de FontAwesome. Pero si la tarjeta está abierta, utilizará la fuente del icono, el icono y el color que se pasaron como accesorios.
Cada una de las cartas puede ser girada. Cuando se toca, el tarjeta de clic ()
Se ejecutará la función, que también se pasa a través de los accesorios. Más adelante verás lo que hace la función, pero por ahora, solo debes saber que se actualiza el estado para revelar el ícono en la tarjeta:
la tarjeta predeterminada de la clase de exportación extiende React.Component render () deja CardSource = FontAwesome; // establece FontAwesome como la fuente de iconos predeterminada let icon_name = 'question-circle'; Deje que icon_color = '# 393939'; if (this.props.is_open) CardSource = this.props.src; icon_name = this.props.name; icon_color = this.props.color; regreso ();
No olvides añadir los estilos:
const styles = StyleSheet.create (card: flex: 1, alignItems: 'center', card_text: fontSize: 50, fontWeight: 'bold');
También usaremos una función de ayuda llamada barajar()
. Esto nos permite ordenar el conjunto de cartas en orden aleatorio para que su orden sea diferente cada vez que se reinicie el juego:
Array.prototype.shuffle = function () var i = this.length, j, temp; si (i == 0) devuelve esto; while (- i) j = Math.floor (Math.random () * (i + 1)); temp = este [i]; este [i] = este [j]; este [j] = temp; devuelve esto;
El componente principal (App.js) contiene la lógica principal de la aplicación y reúne todo. Comience por incluir los paquetes React y Expo que usaremos. Esta vez estamos usando todas las fuentes de iconos de los iconos vectoriales de Expo:
importar reaccionar desde 'reaccionar'; importar StyleSheet, View, Button desde 'react-native'; importe Ionicons, FontAwesome, Entypo desde '@ expo / vector-icons';
A continuación, incluya los componentes y el ayudante que creamos anteriormente:
importar encabezado desde './components/Header'; Importar puntaje desde './components/Score'; importar tarjeta desde './components/Card'; importar ayudantes desde './helpers';
Dentro del constructor, primero creamos la matriz que representa las tarjetas únicas. src
es la fuente del icono, nombre
es el nombre del icono (puede encontrar los nombres en GitHub si desea usar otros iconos), y color
Es, naturalmente, el color del icono:
la clase predeterminada de exportación App extiende React.Component constructor (props) super (props); // vincular las funciones a la clase this.renderCards = this.renderCards.bind (this); this.resetCards = this.resetCards.bind (this); // las fuentes de iconos permiten a sources = 'fontawesome': FontAwesome, 'entypo': Entypo, 'ionicons': Ionicons; // los íconos únicos que se usarán let cards = [src: 'fontawesome', name: 'heart', color: 'red', src: 'entypo', name: 'feather', color: '# 7d4b12 ', src:' entypo ', nombre:' flashlight ', color:' # f7911f ', src:' entypo ', nombre:' flower ', color:' # 37b24d ', src:' entypo ', nombre:' luna ', color:' # ffd43b ', src:' entypo ', nombre:' youtube ', color:' # FF0000 ', src:' entypo ', nombre:' shop ', color: '# 5f5f5f', src: 'fontawesome', nombre: 'github', color: '# 24292e', src: 'fontawesome', nombre: 'skype', color: '# 1686D9', src: 'fontawesome', nombre: 'enviar', color: '# 1c7cd6', src: 'ionicons', nombre: 'ios-magnet', color: '# d61c1c', src: 'ionicons' , nombre: 'logo-facebook', color: '# 3C5B9B']; // siguiente: agregue el código creando el clon y configurando las tarjetas en el estado
Tenga en cuenta que en lugar de especificar directamente la src
como FontAwesome
, Entypo
o Ionicones
Para cada uno de los objetos, estamos usando los nombres de propiedades utilizados en el fuentes
objeto. Esto se debe a que necesitaremos crear una copia de la matriz de tarjetas para que cada tarjeta tenga un par. Creando una copia usando métodos de matriz tales como rebanada()
creará una copia de la matriz, pero el problema es que una vez que los objetos individuales se modifican en la copia o en el original, también se modifican ambas matrices.
Esto nos lleva a la solución a continuación, que es crear un objeto completamente nuevo al convertir el tarjetas
matriz en una cadena y luego analizarla para convertirla de nuevo en una matriz. Esta es la razón por la que estamos usando cadenas, ya que las funciones no se pueden convertir en cadenas. Luego, combinamos los dos para crear la matriz, que contiene todas las tarjetas que necesitamos:
let clone = JSON.parse (JSON.stringify (cards)); // crea una matriz completamente nueva a partir de la matriz de tarjetas this.cards = cards.concat (clon); // combina el original y el clon
A continuación, vaya a través de esa matriz y genere una ID única para cada uno, establezca la fuente del icono y luego establezca un estado cerrado de forma predeterminada:
// agregue el ID, la fuente y establezca el estado predeterminado para cada tarjeta this.cards.map ((obj) => let id = Math.random (). toString (36) .substring (7); obj.id = id ; obj.src = fuentes [obj.src]; obj.is_open = false;);
Ordena las tarjetas al azar y establece el estado predeterminado:
this.cards = this.cards.shuffle (); // ordenar las tarjetas al azar // establecer el estado predeterminado this.state = current_selection: [], // esta matriz contendrá una matriz de objetos de tarjetas que el usuario seleccionó actualmente. Esto solo contendrá dos objetos a la vez. selected_pairs: [], // los nombres de los iconos. Esta matriz se utiliza para excluirlos de la puntuación de selección adicional: 0, // tarjetas de puntuación de usuario predeterminadas: this.cards // las tarjetas barajadas
los hacer()
El método representa el encabezado, las cartas, la puntuación y el botón para restablecer el juego actual. Esta usando el renderRows ()
Función para renderizar las filas de cartas individuales. La pantalla tendrá seis filas que contienen cuatro cartas cada una:
render () return (); this.renderRows.call (this)
Aquí está el código para el renderRows ()
función. Esto usa el getRowContents ()
Función, que es responsable de crear una matriz de matrices con cuatro elementos cada una. Esto nos permite renderizar cada fila, y luego usar otra función para renderizar tarjetas para cada iteración de la mapa()
función:
renderRows () let contents = this.getRowContents (this.state.cards); return contents.map ((cards, index) => return (this.renderCards (tarjetas) ); );
Aquí esta la getRowContents ()
función:
getRowContents (tarjetas) let contents_r = []; dejar contenidos = []; vamos a contar = 0; cards.forEach ((item) => count + = 1; contents.push (item); if (count == 4) contents_r.push (contents) count = 0; contents = [];); devolver contents_r;
Siguiente es el renderCards ()
función. Esto acepta la matriz de objetos de la tarjeta y los procesa a través del Tarjeta
componente. Todo lo que tenemos que hacer aquí es pasar las propiedades individuales de cada objeto de tarjeta como accesorios. Esto se usa para representar el ícono correcto, como se ha visto en el código para el Tarjeta
componente. los tarjeta de clic ()
La función también se pasa como prop. La identificación de la tarjeta se pasa a esa función para que la tarjeta única pueda ser identificada y actualizada:
renderCards (cards) return cards.map ((card, index) => return (); );
Dentro de tarjeta de clic ()
Para ello, obtenemos los detalles de la tarjeta seleccionada y verificamos si debe procesarse más:
clickCard (id) let selected_pairs = this.state.selected_pairs; let current_selection = this.state.current_selection; dejar puntuación = this.state.score; // obtener el índice de la tarjeta actualmente seleccionada let index = this.state.cards.findIndex ((card) => return card.id == id;); deja cards = this.state.cards; // la tarjeta no debería estar abierta y no está en el conjunto de tarjetas cuyos pares ya están seleccionados si (cards [index] .is_open == false && selected_pairs.indexOf (cards [index] .name) === 1) // siguiente: agregar código para procesar la tarjeta seleccionada
Ahora completemos el código para manejar una tarjeta seleccionada.
Primero, abrimos la tarjeta y la agregamos a la matriz de tarjetas actualmente seleccionadas:
tarjetas [índice] .is_open = verdadero; current_selection.push (index: index, name: cards [index] .name); // siguiente: agregue código para determinar si el usuario ha seleccionado el par correcto o no
Una vez que hay dos elementos en el conjunto de tarjetas actualmente seleccionadas, verificamos si los nombres de los íconos son iguales. Si lo son, significa que el usuario ha seleccionado el par correcto. Si no son lo mismo entonces es un par incorrecto. En ese caso, cerramos la primera tarjeta que se seleccionó y luego agregamos un poco de retraso antes de cerrar la segunda tarjeta. (De esta manera el usuario puede ver el ícono de la tarjeta antes de volver al estado cerrado).
if (current_selection.length == 2) if (current_selection [0] .name == current_selection [1] .name) score + = 1; // incrementa la puntuación selected_pairs.push (cards [index] .name); else cards [current_selection [0] .index] .is_open = false; // cierra la primera // demora en cerrar la tarjeta actualmente seleccionada en medio segundo. setTimeout (() => cards [index] .is_open = false; this.setState (cards: cards);, 500); current_selection = []; // siguiente: agregar código para actualizar el estado
Lo último que debemos hacer en el controlador de eventos de clic es actualizar el estado para reflejar los cambios en la interfaz de usuario:
this.setState (score: score, cards: cards, current_selection: current_selection);
Una función relacionada es el controlador de eventos de reinicio. Cuando el Reiniciar botón pulsado, simplemente restauramos el estado predeterminado cerrando todas las tarjetas y barajando.
resetCards () // cierra todas las tarjetas let cards = this.cards.map ((obj) => obj.is_open = false; return obj;); cards = cards.shuffle (); // volver a barajar las tarjetas // actualizar al estado predeterminado this.setState (current_selection: [], selected_pairs: [], cards: cards, score: 0);
Finalmente, agregaremos algunos estilos básicos para hacer que nuestra aplicación se vea bien..
const styles = StyleSheet.create (container: flex: 1, alignSelf: 'stretch', backgroundColor: '#fff', row: flex: 1, flexDirection: 'row', body: flex: 18, justifyContent: 'space-between', padding: 10, marginTop: 20);
Debido a que su servidor de desarrollo Expo ha estado funcionando todo este tiempo, cada cambio debe ser enviado a su dispositivo móvil con recarga en vivo. Prueba la aplicación y asegúrate de que funcione como debe.
¡Eso es! En este tutorial, aprendió a usar Expo XDE para conectar rápidamente una aplicación React Native. Expo es una muy buena manera de comenzar a desarrollar aplicaciones React Native porque elimina la necesidad de instalar una gran cantidad de software que a menudo es motivo de frustración, especialmente para los principiantes. También proporciona herramientas que facilitan la vista previa de la aplicación mientras se desarrolla. Asegúrese de consultar los recursos mencionados en el sitio web de la Expo si desea obtener más información.
Y mientras tanto, eche un vistazo a algunas de nuestras otras publicaciones sobre el desarrollo de aplicaciones nativas React!