React Native — Construindo Apps Nativos com Javascript (parte 1)

(Utilizando a arquitetura flux)


Faz três meses desde a React.js Conf e do grande anúncio dos representantes do facebook revelando que iriam tornar open-source, sua ferramenta de desenvolver aplicativos mobile nativos com Javascript e React.

Quando vi o anúncio e a demonstração fiquei empolgado feito uma menina de 15 anos em sua festa de debutante, o que pode parecer exagero para quem não sabe o quanto eu sou apaixonado por Javascript (mesmo com todas suas falhas) e o quanto React rejuvenesceu essa paixão quando foi lançado (também pelo facebook).

Depois do anúncio as coisas andaram muito rápido, posts, mais posts e até cursos foram publicados sobre a mais nova ferramenta revolucionária do facebook. A maioria das impressões foram ótimas, mas também houve ruins, o que é normal, já que é muito difícil agradar a todos. Em março o facebook cumpriu o prometido e abriu publicamente o código do React Native no github, que foi introduzido com um ótimo post no blog de engenharia do facebook. As coisas estão andando tão rápido que já anunciaram até uma IDE exclusiva para desenvolver com React Native. Então não pisque, pois pode acabar perdendo algo.

Quem não teve tempo ou não se dá muito bem com a língua inglesa pode ter ficado desatualizado ou perdido em meio a tantos acontecimentos em tão pouco tempo. Então nesta série (que vai funcionar exatamente como um tutorial), eu irei tentar iluminar essa escuridão causada pelas dúvidas e desconfianças causadas por mais uma ferramenta super nova e revolucionária, apoiada por aquela grande e respeitada empresa.

O que vamos criar?

Inspirado pelo ótimo post do Colin Eberhardt, vou guiá-lo na criação de um simples aplicativo de reserva de hotéis, utilizando um wrapper que criei em cima da API de hotéis Hotel Urbano. Vou também, diferentemente do post acima, propor uma arquitetura baseada em flux (olha o facebook aqui de novo) que vai nos permitir vislumbrar como seria a arquitetura de um aplicativo escalável e manutenível criado com React Native.

O "produto" final.

Ao final desta série teremos um aplicativo completo e funcional, e você terá uma ampla visão de como é desenvolver utilizando React Native e seu ecossistema.

Para quem não tiver paciência de continuar ou achou somente a introdução e os links o suficiente, disponibilizei o código deste projeto no github para quem quiser "forkar" e começar a brincar.

Para quem vai continuar, é preciso atender alguns requisitos obrigatórios, como por exemplo, ter um OS X com a última versão do Xcode instalado. Então infelizmente a galera do Windows e Linux não verá o App rodando.


Preparando o ambiente

Vamos prosseguindo passo a passo, ok?

  1. Instale o Homebrew (um package manager do OS X, a maneira mais fácil de instalar as dependências necessárias do React Native);
  2. No terminal, execute: brew install node (irá instalar o nodejs, e com ele, o npm);
  3. Ainda no terminal, execute: brew install watchman (é recomendado a instalação do watchman para você não ter problemas durante o desenvolvimento, mais especificamente com o build contínuo);
  4. De novo no terminal: npm install -g react-native-cli (finalmente instalando a o utilitário de terminal do React Native);
  5. Nem ouse em fechar seu terminal, vá para o seu diretório de projetos e execute: react-native init ReactHotelFinder (irá criar o diretório do projeto e baixar o repositório starter do React Native);
  6. cd ReactHotelFinder && npm start (irá entrar no diretório do projeto e iniciar o watcher que fará build do nosso aplicativo sempre que fizermos uma mudança);
  7. Abra o projeto no Xcode (arquivo ReactHotelFinder.xcodeproj no diretório do projeto) e clique em Run ou pressione Cmd+R (irá abrir o simulador e rodar o starter app dentro dele);
  8. Como o Xcode não foi projetado para desenvolver em javascript, recomendo que, em paralelo, você abra o projeto em uma IDE que suporte javascript (se possível com suporte à ES6, a nova versão do ECMAscript, linguagem que o javascript implementa), minhas sugestões ficam entre Sublime Text, Atom ou Brackets.

Let's get coding!

Vamos começar com algo simples, remova tudo que está dentro do arquivo index.ios.js e vamos começar do zero, com o seguinte código:

'use strict';
//Importando react native
var React = require('react-native');
//Extraindo os componentes necessários da biblioteca
var {
AppRegistry,
StyleSheet,
Text,
View,
Component
} = React;
//Criando o componente principal, container para todo App
class ReactHotelFinderTut extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.helloWorld}>
Hello World
</Text>
</View>
);
}
}
//Criando estilos dos components, isso te lembra algo?
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
helloWorld: {
fontSize: 32,
textAlign: 'center',
fontWeight: 'bold'
}
});
//Registrando componente principal, sem isso o app não funciona
AppRegistry.registerComponent(
'ReactHotelFinderTut',
() => ReactHotelFinderTut
);
Hello React Native!

Vá no simulador e pressione Cmd+R e como num passe de mágica, como se estivéssemos atualizando um browser (garanto que não estamos), você verá o aplicativo atualizar, ficando como vê na imagem ao lado.

Aqui, um desenvolvedor mobile, sendo de iOS, android ou WP, provavelmente já teria múltiplos orgasmos, já que "elimina" o loop infinito de code -> build -> run (ok, tecnicamente não, na verdade foi só automatizado), e em frações de segundos é possível ver suas mudanças no aplicativo rodando.

Outra coisa importante a notar, é o quão parecido com desenvolver para web React Native é, a notação JSX e os estilos baseados em flexbox do CSS torna tudo muito simples para quem é oriundo do mundo web, mas ainda sim é de fácil assimilação mesmo para desenvolvedores iniciantes, devido ao fato de ser tão declarativo.

Explicando mais detalhadamente o código acima, View é um componente genérico que pode conter um ou mais componentes filhos, utilizamos ele como container para um componente Text que, como pode imaginar, renderiza um texto na tela. Declaramos que nosso container ocupará 100% da largura e altura da tela com flex: 1, que seus componentes filhos serão centralizados horizontalmente e verticalmente na tela com justifyContent: ‘center’ e alignItems: ‘center’ e que seu background terá uma cor azul clara com backgroundColor: ‘#F5FCFF’. Já o texto declaramos com o tamanho 32 com fontSize: 32 (eu sei, óbvio), alinhado ao centro com text-align: center e negrito com fontWeight: 'bold'. Simples não?

O que StyleSheet.create() faz, é somente verificar se estamos utilizando regras suportadas pelo componente, do contrário poderíamos ter colocado os estilos como um simples objeto javascript no atributo style do componente, mas é sempre bom separar as coisas. Mais para frente, com as regras de estilos se acumulando, recomendo até colocá-las em outro arquivo para melhorar a manutenibilidade.

Vermelho significa que algo está errado. Simples assim.

Outra abordagem dos desenvolvedores do React Native que eu particularmente gostei foi como eles exibem qualquer erro. Se você esquecer mesmo que seja uma vírgula, no próximo reload você será presenteado com uma uma detalhada descrição do erro e um chamativo background vermelho. Sabemos que e fácil errar ao codar, difícil é achar o erro às vezes, e essa abordagem diminui bastante o tempo que passamos minerando typos e outros erros. React já faz isso muito bem, nunca tinha visto descrições de erro tão claras e detalhadas, e é bom ver que eles trouxeram a mesma abordagem para o React Native.

O componente Navigator

Nenhum aplicativo é composto de somente uma tela (não os melhores pelo menos), logo necessitamos de maneiras para construir uma navegação para o usuário, onde ele consiga prosseguir para as telas internas e voltar quando achar necessário, para isso vamos utilizar o componente NavigatorIOS que serve exatamente para este propósito.

Crie uma pasta chamada app/ na raíz do projeto, é nela que iremos colocar todos os componentes e outras dependências do aplicativo. Dentro da pasta app/ crie outro diretório chamado components/ e dentro dele um arquivo chamado SearchScreen.js que irá conter nosso componente da tela de busca do aplicativo. Este arquivo irá conter o seguinte código:

'use strict';
var React = require('react-native');
var {
Component,
View,
Text,
StyleSheet
} = React;
class SearchScreen extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.description}>
Tela de busca de hotéis
</Text>
</View>
);
}
}
//Estilos do componente
var styles = StyleSheet.create({
container: {
marginTop: 65,
paddingTop: 15,
paddingBottom: 15,
paddingLeft: 30,
paddingRight: 30,
alignItems: 'center'
},
description: {
marginTop: 10,
fontSize: 18,
textAlign: 'center',
color: '#656565'
}
});
//Exportando componente
module.exports = SearchScreen;

Nada de novo aqui, a não ser as regras de estilo, que são bem auto-explicativas. O container vai ter uma margem superior de 65px, padding superior e inferior de 15px e padding lateral de 30px. O texto uma margem superior de 10px, tamanho 18px, alinhado ao centro e uma cor cinza escura.

Atualize o arquivo index.ios.js com o seguinte código:

'use strict';
//Importando react native
var React = require('react-native');
//Importando o componente SearchScreen
var SearchScreen = require('./app/components/SearchScreen');
//Extraindo os componentes necessários da biblioteca
var {
AppRegistry,
StyleSheet,
NavigatorIOS,
Component
} = React;
//Criando o componente principal, container para todo App
class ReactHotelFinderTut extends Component {
render() {
return (
<NavigatorIOS
style={{flex: 1}}
tintColor="#F9A11B"
initialRoute={{
title: 'React Hotel Finder',
component: SearchScreen
}} />
);
}
}
//Registrando componente principal, sem isso o app não funciona
AppRegistry.registerComponent(
'ReactHotelFinderTut',
() => ReactHotelFinderTut
);
As coisas vão tomando forma com o componente NavigatorIOS

Modificamos o arquivo index.ios.js para importar o componente SearchScreen e passá-lo como parâmetro para o componente NavigatorIOS pelo atributo initialRoute onde também definimos o título do componente. A partir daí o NavigatorIOS tomará conta de instanciar e exibir o nosso componente da tela de busca. O atributo tintColor serve para configurar a cor dos botões do cabeçalho.

Pressione Cmd+R e voilá! Nosso aplicativo já está tomando forma. Perceba que o NavigatorIOS é composto pelo cabeçalho (que irá conter os botões e o título) e nosso componente da tela de busca (que por enquanto só tem uma descrição).


Se você chegou até aqui e continuou interessado, siga o nosso blog que muito em breve iremos postar a próxima parte desta série, onde falarei da arquitetura flux e como iremos aplicá-la neste projeto, além de finalizarmos a tela de busca. Criei um repositório separado para quem prefere acompanhar a série commit à commit.

Então até lá, e enquanto isso estamos à disposição para sanar quaisquer dúvidas e problemas que possam ter encontrado.

Abraço!

Equipe ignit.io by Allan Baptista

Show your support

Clapping shows how much you appreciated ignit.io’s story.