React Native na Web

No items found.
14/4/2020
Rodrigo Mello
Rodrigo Mello
Tech Lead

Entusiasta de interfaces digitais

Está sem tempo para ler? Aperte o play para escutar o artigo.

Antes de se aventurar com React Native rodando na Web, é essencial que antes conheça alguns conceitos e estratégias de compartilhamento de código entre React e React Native, afinal, a biblioteca react-native-web é só isso, uma de estratégia que tem como finalidade compartilhar o máximo possível da sua aplicação web com uma aplicação mobile.

Rodar React Native na Web não é novo, alguns grandes apps já utilizam, como Skype e Twitter, apesar do react-native-web ser mantida pela comunidade e não oficialmente pelo Facebook, é uma tecnologia estável o suficiente para você pode usar neste instante, diferentemente do Flutter Web que está em beta há mais de um ano.

Estratégias de compartilhamento de código

Existem duas formas básicas de compartilhamento de código entre React e React Native, são elas o “alias” e o “container”. 

Importante: os 2 termos foram criados por mim mesmo para me referir às estratégias. A ideia de componente primitivo (primitive component) é a mesma do alias, achei melhor usar alias para exemplificar do que propriamente explicar componentes primitivos.

Alias

Um “alias” seria um apelido, um atalho, uma espécie de “de para”. O React Native não roda na Web, ele foi feito para rodar em dispositivos móveis, então quando falamos de React Native Web na verdade estamos falando de uma biblioteca que substituirá o “react-native” pelo “react-native-web” durante o build para que seja possível então “simular” o comportamento do React Native no navegador web.


Se você sabe Webpack, é muito simples configurar uma aplicação React Native para rodar na Web, basta adicionar as configurações do seu Webpack um alias dessa maneira:


react native


Simples assim!

O webpack substituirá tudo que é react-native por react-native-web antes de buildar. O build do webpack não influencia o build do react-native que serve tanto para iOS quanto para Android

Vale lembrar que se for seguir nessa estratégia de usar react-native-cli com webpack, você deve também configurar o webpack para rodar react, css, imagens, etc. 

Seria uma configuração normal do webpack para React. Ou seja, você pode criar um projeto novo de React Native normalmente e depois criar seu webpack dentro desse projeto do react native.

Caso você não tenho familiaridade com o webpack, uma ótima alternativa é usar o Expo. O Expor hoje já vem por padrão o react-native-we configurado. Ou seja, o expo já fez essa configuração do webpack pra você, se olhar os scripts dentro do package.json verá que existe um para rodar na web.

Zupcast: Ouça Agora!


Container

Uma forma muito conhecida no mundo react é a ideia de componente container e componente de apresentação (presentation). 

Essa estratégia de compartilhamento não está ligada ao react-native-web ou qualquer outro alias, mas sim um recurso muito útil mas conhecido por poucos do react-native que é a identificação de arquivos por determinada plataforma se baseando na extensão, ou seja, se você tem um diretório Button e dentro dele você pode ter um index.js para cada plataforma, um index.android.js para android, index.ios.js para ios, index.web.js para web ou index.native.js para andorid e ios e index.js que é o padrão de todas as plataformas.


Com isso, você poderia ter um componente container “genérico”, ele não seria nem react-native nem react web, seria apenas react, pois apenas as importações que estaria nesse container seriam diferentes para cada plataforma, já o container seria único. 

Vamos manter o exemplo do Buttton.

Este seria o button para web:

button


E este para react native:

button react


Ambos estão na mesma pasta, o que muda é só a extensão. Na hora de importar basta usar “importa Button from ‘../Components/Button’”. Esta importação vale para qualquer plataforma, basta importar uma vez.

Aqui seria esse botão aplicado em um componente container:


Todos os componentes usados neste formulário são componentes de apresentação com 2 indexs, um para nativo (Component.native.js) e outro para web (Component.js).

Alias ou Container, qual usar?

Um simula o comportamento do nativo para a web o outro cria um index para cada plataforma. Portanto, é difícil dizer qual é melhor que qual, já que são estratégias diferentes para compartilhar código entre react e react-native, porém é importante entendermos os pontos fortes e fracos de cada estratégia. 

E claro, nada impede de usarmos as duas no mesmo projeto se for necessário.

O Alias é mais rápido de desenvolver, basicamente você vai escrever uma vez e vai rodar pra tudo, Android, iOS e Web, porém da mesma forma que existem diferenças entre andorid e ios, essas diferenças são muito maiores quando colocamos a web no meio. 

Lembre-se, a ideia do react-native-web é simular o comportamento do nativo na web, então não são todos os recursos que vão funcionar na web, essas limitações devem ficar no seu radar. 

Importante: a leitura da documentação do react-native-web é obrigatória para entender quais são essas limitações.

O Container segue a ideia que compartilhar a store (redux), as chamadas de api, os containers com as lógicas. Compartilhar isso já é o suficiente para muitos, mantendo as coisas separadas, você consegue ter uma clareza maior o que é de cada ambiente.


Navegação/Rotas

Taí um ponto que o nativo e o web são totalmente diferentes, não é possível compartilhar esse recurso entre as plataformas. 

No react-navigation a navegação é baseada em stacks, cada um tem um fluxo específico, fluxo no qual está associada ao botão voltar, já na web não temos isso, na web temos apenas o histórico geral de onde você estava (react-router-dom). 

Uma opção seria usar react-router-native, mas até nele seria necessário configurações adicionais para fazer rodar nas duas plataformas. O controle da navegação assim sendo, deve ser configurado a parte para react-native e web, ainda não há forma fácil de compartilhar essa configuração de navegação entre diferentes plataformas.

Responsivo

O React Native não usa css, logo não usa mediaqueries, com isso o controle do responsivo fica à cargo do javascript controlar os breakpoints da tela. Basicamente você pode usar alguma lib para isso, ou criar um listener no módulo Dimensions do react-native e colocar a altura e largura dentro do redux pra que seja acessível a todos os componentes e que caso o valor mude, os componentes sejam renderizados, exibindo-os ou não, ou mudando sua aparência ou não baseando-se na largura e altura armazenadas na store.

Plugins

Plugins são um universo à parte, pois geralmente cada lib é pensada para apenas uma das duas plataformas, web ou native. E como vimos antes, o react-native por si só não é capaz de rodar na web sendo necessário um alias com o react-native-web para tal. Essa ideia também vale para plug-ins, assim como você não pode pegar uma lib que roda no android e esperar que ela roda na web, você não pode pegar um lib conhecida na web e esperar que roda no android, mas há como contornar isso.

Alias de libs

Está se tornando comum bibliotecas com suporte para native e web, porém não ao mesmo tempo, não com o mesmo fonte, mas é a mesma lib, exemplo do “react-content-loader” (que é para web), se você importar como “react-content-loader/native” o uso é para native. 

Como usar isso então? Simples, é só usar a ideia de container, cria-se um diretórios “./lib/react-content-loader” e dentro 2 arquivos um index.js e outro index.native.js, você vai importar e exportar em seguida a lib dentro desses arquivos.


Alias do react-native-web dentro do fonte da lib

Vamos pegar a lib “react-native-calendars” como exemplo, como o próprio nome diz é uma lib para react-native, porém queremos fazê-la rodar na web, como podemos fazer isso? 

Nós podemos fazer o webpack ler tudo o que está dentro do diretório dessa lib para que então seja possível que o alias que temos no react-native para react-native-web também seja executado dentro do react-native-calendars, ou seja, por padrão o nosso alias do react-native-web só funciona no nosso projeto, não roda nas dependências (libs de terceiros) para isso existe um esforço adicional pra fazer isso acontecer, e essa configuração varia se você está usando Expo ou Webpack. 

Como testar facilmente isso sem configuração adicional? Baixar o código fonte da lib que você quer e colocar a pasta dentro do seu projeto, com isso o webpack vai ler por padrão o código sendo possível fazer o alias do react-native-web, essa forma mesmo sendo mais prática não é recomendada, uma vez que você perde o versionamento dessa lib. 

Resumindo, você deve configurar o loader no seu webpack a incluir (include) a lib que deseja buildar junto com o seu projeto para que o alias do reac-native-web também funcione nela.


Container

Você também pode usar a ideia de container com libs diferentes.  

Imagine que você quer usar uma lib conhecida da web e outra lib diferente que também é conhecida no react-native, ambas são feitos por pessoas diferentes porém resolvem a mesma dor, você pode criar um diretório /lib/UmaLibIncrivel com 2 arquivos, um index.js para web e um index.native.js para native, porém você deve ter o cuidado de criar uma “interface” para unificar tudo, se você trabalhar com typescript vai entender de cara o problema. 

Cada lib tem suas próprias opções e seus próprios recursos, mesmo duas libs parecidas ainda terão muitas diferenças de implantação, para pode ter uma lib web e outra lib native rodando em paralelo você precisa criar um wrapper dentro desses arquios indexes para que a interface (métodos, props) sejam a mesma tanto para web e native.


API Universal

E finalmente a melhor solução (que infelizmente é a menos usada pelos criados de libs), ela é uma API única, uma lib única que pode ser importada tanto para web quanto para native. Exemplo: expo-camera.


Conclusão

Se parece confuso para você essa misturas de arquivos com alias, containers, etc, pense assim: web e native são plataformas totalmente diferentes, com comportamentos diferentes, o react-native-web já resolve muitos desses problemas pra gente, ainda não é possível escrever um só código e esperar que ele rode em tudo por padrão, mas existe muita gente correndo atrás disso. 

Para se trabalhar com código react e react-native é necessário ter um conhecimento que vai além do básico, tanto de web (dom) quando de react-native para que essa mistura de conceitos faça mais sentido, existe muitas coisas que existem em uma plataforma que não existem em outra, aí cabe você adaptar isso, não existe um guia de boas práticas, temos que usar o bom senso.

Talvez para um iniciante em React isso seja demais, muitos conceitos a serem levados em consideração ao mesmo tempo, talvez para ele um clássica webview resolva seu problema.

Mas se você é mais experiente e sua empresa quer ter um produto web e mobile, eu sinceramente não veja opção melhor no mercado para se ter um app multiplataforma do que usar React e React Native juntos.

Com isso você consegue ter uma aplicação rodando em pelo menos 3 plataformas (daria pra ter em mais, como Windows e Mac  com react-native-windows mas requer mais configurações) com apenas um time, por mais que a princípio pareça complicado, ainda é muito mais simples do que criar 3 apps em 3 plataformas nativamente, o que ao meu entender é desnecessário.

Aula aberta React Native na Web

Quer complementar seu estudo sobre o tema? Fizemos um webinar para discutir com a comunidade e tirar dúvidas ao vivo. Assista agora! 

E você, qual sua opinião sobre o assunto? Escreva nos comentários suas dúvidas, sugestões e questionamentos pra continuarmos o papo. 

O que você achou deste conteúdo?
Quer receber nossos conteúdos?
Seu cadastro foi efetuado com sucesso! Enviaremos as novidades no seu email.
Oops! Something went wrong while submitting the form.