Transformando uma aplicação React em um aplicativo nativo (Parte 2)

Criando a arquitetura do zero, explicando passo a passo.

Separei esse artigo em duas partes. Na segunda parte que você está lendo agora, entrarei mais afundo e criarei do zero a arquitetura, explicando passo a passo. Na primeira parte, eu mostro a estrutura de pensamento, que pode ajudar a entender se essa estratégia irá se adequar ao seu caso.

Iniciando o projeto

Para essa primeira parte vamos precisar criar dois projetos, um para a aplicação web que será feita em React e outro para a aplicação nativa que será feita com React Native.

Não será abordado o setup inicial para rodar as aplicações React e React Native, mas você pode ler sobre isso aqui.

Para este artigo, eu criarei somente um repositório no Github, mas em um caso real onde terá outras pessoas codando, eu prefiro quebrar em dois repositórios para ficar mais organizado.

No fim deste artigo há a URL para o repositório, caso queira pular o passo a passo.

Criação da aplicação web (React)

Para facilitar a criação desse artigo e não misturar com outros assuntos e conceitos, irei usar o CRA (create-react-app) para iniciarmos um projeto React.

Vamos lá!

npx create-react-app web

Com o projeto criado, iremos colocar variáveis de ambiente no script de start e build para diferenciarmos nossa aplicação web e nativa quando precisarmos e adicionar um arquivo de estilos já pronto que vou deixar disponível aqui. Basta copiar e salvar no arquivo index.css.

Agora precisamos criar um útil para recebermos essa informação, então irei criar uma pasta utils, e um arquivo chamado isApp.js com o seguinte código:

Com isso pronto, irei adicionar o react-router-dom para criarmos nossas rotas. Caso queira se aprofundar na biblioteca, você pode encontrar mais informações aqui.

yarn add react-router-dom ou npm install react-router-dom

Arquivo: App.js

Como mostrado nó código acima, separei em outros arquivos o Root, Home e About para deixar mais organizado.

> Arquivo: ./pages/Home/index.js

> Arquivo: ./pages/About/index.js

> Arquivo: Root.js

No código acima, importei um módulo que eu criei chamado postMessage. Esse módulo tem a responsabilidade de se comunicar diretamente com o lado nativo via o método ReactNativeWebView.postMessage, que é inserido no window, assim usamos ele para sempre avisar o aplicativo nativo quando uma rota foi alterada e qual é a nova rota atual. Mais para baixo irei mostrar um caso real de onde podemos usar essa informação.

> Arquivo: utils/postMessage.js

Com essa comunicação podemos fazer várias outras coisas, como alternar entre uma página nativa e uma página web por exemplo.

Criação da aplicação nativa (React Native)

Agora com a parte web já preparada, podemos criar o nosso projeto React Native!

O comando abaixo vai iniciar o projeto, ele pode demorar um pouco dependendo da sua conexão.

npx react-native init app --template react-native-web-to-native-template

Reparem no parâmetro –template, onde eu passo o nome do boilerplate que deixei preparado com algumas coisas que iremos precisar.

Com o projeto criado, iremos abrir o arquvio webview.js que se encontrará no caminho src > constants > webview.js para atualizarmos a URL inicial do aplicativo o rootUrl. Como estamos trabalhando localmente, iremos colocar localhost com a porta default que o CRA criou para nossa aplicação web que foi a 3000, ficando dessa maneira abaixo:

export const rootUrl = 'http://localhost:3000/'

Agora iremos rodar o projeto e ver como está!

yarn ios ou yarn android

Com o nosso aplicativo rodando, agora podemos perceber no topo da tela que a barra superior do sistema não bate com a cor da aplicação. De acordo com o estilo já adicionado no começo do artigo, as cores são:

Com isso, iremos usar a informação que mandamos via postMessage para conseguir manipular a cor do sistema conforme a página atual. Mas antes, iremos ver como a comunicação via postMessage funciona do lado do aplicativo e, para ficar claro, terei que passar por alguns arquivos.

> Trecho do arquivo: src/pages/Main/index.js (A página que renderiza o WebView)

No trecho acima, podemos perceber o uso do onMessage, o callback que o componente WebView irá chamar quando o método ReactNativeWebView.postMessage for executado. No nosso caso estamos passando o handleOnMessage como callback, então vamos ver o que ele está fazendo.

> Trecho do arquivo: src/pages/Main/hooks/useWebview.js (Um custom hook que estamos chamando no src/pages/Main/index.js)

No nosso callback, recebemos o evento e conseguimos extrair a informação que foi passada da nossa aplicação web acessando o event.nativeEvent.data. Como enviamos um json formatado como string, pois o postMessage só aceita string, agora podemos transformar nossa string para json de volta.

O messageEvents faz um papel bem importante de roteamento. Como o método que estamos usando para comunicação não nos fornece nenhuma estrutura (ele apenas transmite texto de um lado para o outro), foi preciso criar essa estrutura de roteamento para facilitar a nossa vida e deixar mais organizado. Na nomenclatura vou usar o termo event para facilitar o entendimento.

> Arquivo: src/utils/messageEvents/index.js

Como mostrado acima, usei RamdaJS para criar essa estrutura (também poderia ser feita com switch case), que pega a propriedade eventName passada da aplicação web e endereça a função que vai receber e lidar com os dados. No caso atual estamos lidando somente com o routeChange que criamos, então vamos entender o que ele está fazendo.

> Arquivo: src/utils/messageEvents/routeChange.js

O routeChange verifica se o href existe e, caso exista, ele atualiza o estado que informa a url atual e também atualiza o status do canGoBack, que é quem controla se o app pode ou não fechar em uma ação de voltar.

Com tudo isso pronto e explicado, agora temos a informação da url atual no lado do React Native e podemos manipular a cor do sistema para que sempre fique igual ao topo da aplicação web.

> Arquivo: src/pages/Main/hooks/propsMapper.js

No custom hooks acima, pegamos a url atual que é passada para ele, extraimos a url limpa de query strings e passamos para a função getUrlToStatusBarColor, que está mapeando as urls e as respectivas cores e então retornamos isso diretamente para o componente Main que vai passar para o componente StatusBar.

> Trecho do arquivo: src/constants/webview.js

Estamos adicionando no código acima as cores no mapa por url.

> Trecho do arquivo: pages/Main/index.js

No código acima, passamos a propriedade da cor para o StatusBar e para o SafeAreaView para de fato fazer as cores alterarem, vamos ver como ficou! Se você já estiver com o projeto rodando é só atualizar, se não tiver é só rodar o yarn ios ou yarn android ou olhar o gif abaixo:

Repositório com o código que desenvolvemos aqui nesse artigo.

Conclusão

Encerro por aqui esse artigo, mas se quiser saber mais sobre essa implementação, leia a primeira parte desse post, onde mostro como chegamos nessa solução, o motivo e os ganhos que você pode ter caso esteja em um cenário parecido.

Espero que consigam adaptar no cenário de vocês e qualquer dúvida ou sugestão estarei respondendo os campos de comentários, obrigado!

Método postMessage que o React Native injeta no window
Parâmetro onMessage do componente WebView
Repositório com o código do artigo
Método postMessage do componente WebView
Parte um desse artigo

Comments: