Creando un App Híbrida con ReactNative

Introducción

Este tutorial comienza justo donde termina la el post anterior sobre la instalación de React-Native: este es el post

Daré por hecho que ya tienes instalado React Native junto con todas las herramientas de las que hablamos en ese post, y que además ya creaste el proyecto "FixterGeek" y que tu aplicación está corriendo en el emulador.
Si esto es así estas listo para seguir y conocer algunos de los componentes y algunas librerías geniales que nos ayudan a desarrollar apps híbridas más rápido (como si React-Native no fuera suficientemente rápido).


Centralizar nuestra App

Vamos a usar el mismo archivo index para las 2 plataformas

React Native por default crea un conjunto de carpetas con las que trabaja y puede compilar los archivos necesarios para ejecutar nuestra app en iOs y Android de manera independiente, pero esto crea un doble trabajo ya que tenemos un archivo index.ios.js y un archivo index.android.js lo que implicaría tener que modificar 2 archivos y terminaríamos creando 2 apps diferentes, por suerte si sabemos usar javascript podemos echar mano de la importación de archivos para resolver esto y quedarnos solo con un archivo principal para las 2 paltaformas.

En este post usaré sintaxis ES6 (EcmaScript2015) ya qué React Native CLI ya creo el archivo con todo lo necesario para transpilar y compilar nuestro código a los lenguajes necesarios y podemos aprovechar para programar de forma más moderna, cómoda y ¡orientado a objetos! =D

  • así que comencemos creando nuestro archivo principal.
    en la carpeta de nuestro proyecto FixterGeek vamos a crear la carpeta components y dentro crearemos el archivo App.js la mayúscula es importante ya que contendrá nuestra primer clase.

    mkdir components  
    touch App.js  
    

    esto puedes hacerlo también directamente en tu editor de código ;)

  • Ahora creamos nuestro Hola mundo super básico, dentro de nuestro archivo App.js, para esto puedes usar tu editor de texto favorito, yo usaré Brackets el cual es gratuito, puedes usar sublimeText o a mi parecer el mejor para React que es Webstorm (solo que es de costo U_U)

    import React, { Component } from 'react';  
    import { View, Text, StyleSheet } from 'react-native';
    
    
    class App extends Component {  
        render(){
            return(
                <View style={styles.container}>
                    <Text >FixterGeek</Text>
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({  
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
        }
    });
    
    export default App;  
    

    Podemos notar varias cosas en este pequeño componente:

    Estamos importando componentes que ya tiene react-native, que funcionan para ambas plataformas (iOS y Android) desde 'react-native'


    dentro de la función return de render, estamos devolviendo nuestro código Jsx con una simple View y un Text dentro (View es el equivalente genérico de un div usando react para web)


    Estamos agregando estilos con el formato más utilizado de React Native el cual es en forma de objeto, no hay gran diferencia con el css tradicional solo hay que recordar que NO es css y que al ser un objeto de JS se escribe en camelCase puedes saber más aquí


    Estamos utilizando FlexBox para acomodar nuestors elementos, es bueno que aprendas Flex ya que es ampliamente utilizado sobre React Native para resolver posiciones (grid)


    Al final del archivo exportamos como default la clase App (esto es importante)

  • Continuamos editando nuestros archivos index.ios.js e index.android.js vamos a sustituir la clase que tiene dentro por la importación de nuestra clase App dentro de nuestro archivo App.js asi:

    index.android.js

    import { AppRegistry } from 'react-native';  
    import FixterGeek from './components/App';
    
    AppRegistry.registerComponent('FixterGeek', () => FixterGeek);
    

    Notese que estamos importando la clase App que exportamos como default en App.js pero estamos nombrandole igual que nuestro proyecto creado con react-native init FixterGeek, por eso le llamamos Fixtergeek


    De esta manera el método AppRegistry sigue registrando correctamente nuestra clase con el nombre de nuestro proyecto.


  • Hacemos lo mismo con index.ios.js (puedes omitir esto si no estás en Mac)

    index.ios.js

    import { AppRegistry } from 'react-native';  
    import FixterGeek from './components/App';
    
    AppRegistry.registerComponent('FixterGeek', () => FixterGeek);
    

  • Podemos probar!! =D vamos a correr nuestra app, nuevamente y si todo esta correcto, podremos ver nuestro unico componente en ambas plataformas. corremos:

    react-native run-android  
    

    y si estamos en Mac también podemos correr:

    react-native run-ios  
    

    y veríamos algo como esto:

    ¡Genial! lo lograste! ahora nuestras 2 apps nativas corren el mismo componente =D

    Mismos componentes diferentes plataformas

    vamos a agregarle una libreria bien chingona

    Muchos de los temas que se abordan en la comunidad de desarrollo con react Native tienen que ver con el problema de trabajar solo código para ambas plataformas. ¿Cual es el problema?

    Imagina que quieres hacer una aplicación Android con elementos de Material Design que se sienta espectacular en Android y haz puesto mucho empeño para que luzca genial, a la hora de probarla se ve perfecta en Android, pero cuando la corres en iOS, el UX no es exactamente el que un usuario iOS esperaría, es como tener una App android en iOS o puede resultar al revés; tener una app hermosa en iOs que al correr en Android no se siente como nativa de Android.

    Y si queremos resolver esto pues terminamos creando una App para cada plataforma con código diferente cada una lo cual resulta en una tarea similar a crear las apps de forma nativa en Xcode y Android Studio con sus respectivas diferencias.

    Por suerte Hay muchas maneras de resolver este problema, una de ellas ya viene con React Native, podemos tener 2 métodos render uno para cada plataforma y así solo preocuparnos por la lógica de nuestra aplicación separando la parte visual de cada app, pero lo dejaremos para un post futuro, ahora me gustaria abordar una manera mucho más simple y que a la larga seguro te servirá para tus desarrollos. Y es instalar una librería de componentes que funcionan diferente para cada plataforma.

    Instalamos NativeBase

    npm install native-base --save  
    

    posteriormente linkeamos todos las dependencias que esta librería utiliza, cómo los iconos. con un comando muy sencillo:

    react-native link  
    

    Y estamos listos para utilizar algunos de los componentes de esta increible librería

  • Vamos nuevamente a nuestra clase App en nuestro archivo App.js que está dentro de components/

    import React, { Component } from 'react';  
    import { View, Text, StyleSheet } from 'react-native';  
    import { Container, Header, Title, Content, Footer, FooterTab, Button, Left, Right, Body, Icon } from 'native-base';
    
    class App extends Component {  
        render(){
            return(
                <Container>
                    <Header>
                        <Left>
                            <Button transparent>
                                <Icon name='menu' />
                            </Button>
                        </Left>
                        <Body>
                            <Title>Header</Title>
                        </Body>
                        <Right />
                    </Header>
                    <Content>
                        <View style={styles.container}>
                            <Text>FixterGeek</Text>
                        </View>
                    </Content>
                    <Footer>
                        <FooterTab>
                            <Button full>
                                <Text>Footer</Text>
                            </Button>
                        </FooterTab>
                    </Footer>
                </Container>
            );
        }
    }
    
    const styles = StyleSheet.create({  
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
        }
    });
    
    export default App;
    

    De este código notese:

    Hemos importado una lista de componentes que vienen desde la librería NativeBase


    Los hemos usado para darle forma a nuestra app


    nuestro View y Text que teníamos originalmente quedo dentro del componente Content

  • Es hora de probar nuestra pequeña modificación.Para esto es necesario volver a correr el comando:

    react-native run-android  
    ó
    react-native run-ios  
    

    Esto porque debe cargar la nueva librería de componentes, posteriormente bastaría con ir al emulador que está corriendo y hacer cmd + r en iOS y presionar doble vez R en Android para ver los cambios reflejarse.

    Como puedes ver, tenemos la misma app renderizada de forma diferente por cada sistema operativo, inclusive si das clic al footer en Android tendrá el efecto de olas de Material design. Esto nos va a permitir escribir código 1 sola vez y aún así obtener el mejor UX para cada dispositivo. ¿No es genial?

    Vamos a dejar este Post hasta aquí. Pero proximamente vamos a seguir trabajando con esta librería y vamos a crear cosas geniales para ambos sistemas operativos. Nos leemos pronto ;)