Guia de desenvolvimento de aplicativos da Web nativos de reação

Você acordou. O sol está brilhando, os pássaros estão cantando. No mundo, ninguém está em guerra com ninguém, ninguém está morrendo de fome, e o mesmo código pode ser usado em projetos da Web e em aplicativos nativos. Como seria bom! Infelizmente, apenas o código universal pode ser visto no horizonte, mas o caminho para ele, ainda hoje, ainda é cheio de surpresas.

imagem

O material, cuja tradução publicamos hoje, é um guia pequeno, mas bastante detalhado, para o desenvolvimento de aplicativos universais usando o React Native.

Por que isso é tudo?


Hoje, a abreviatura "PWA" ( Progressive Web Apps , aplicativos progressivos da Web) é conhecida por todos; esse acrônimo de três letras parece ser apenas uma baleia em um mar de termos técnicos. Mas essa tecnologia popular ainda não está isenta de falhas . Existem muitas dificuldades tecnológicas associadas a esses aplicativos, há situações em que um desenvolvedor é forçado a criar simultaneamente aplicativos nativos e da web. Aqui está um bom artigo comparando o PWA e aplicativos nativos.

Talvez os negócios devam se concentrar apenas em aplicativos nativos? Não, não vale a pena. Este é um grande erro. Como resultado, o desenvolvimento de um único aplicativo universal se torna uma etapa lógica. Isso permite reduzir o tempo de desenvolvimento, reduzir o custo de criação e suporte a projetos. São essas características das aplicações universais que me levaram a um pequeno experimento.

Este é um exemplo de aplicação universal do campo do comércio eletrônico para encomendar alimentos. Após o experimento, criei um modelo para projetos futuros e para futuras pesquisas.


Papu é um aplicativo de pedidos de alimentos desenvolvido para Android, iOS e web

Blocos de construção de aplicativos


Aqui usamos o React, portanto, precisamos separar a lógica do aplicativo da interface do usuário. É melhor usar algum tipo de sistema para controlar o estado de um aplicativo como Redux ou Mobx. Tal movimento imediatamente torna universal a lógica do aplicativo funcionando. Sem alterações, pode ser usado em diferentes plataformas.

A parte visual do aplicativo é outra conversa. Para construir a interface do aplicativo, você precisa ter um conjunto universal de primitivos, blocos de construção básicos. Eles devem funcionar na Web e no ambiente nativo. Infelizmente, o idioma da web e o idioma das plataformas nativas são duas coisas diferentes.

Por exemplo, um contêiner da Web padrão entrará em contato com você assim:

<div> !  -   !</div> 

E nativo - assim:

 <View>!  -    React Native</View> 

Algumas pessoas inteligentes encontraram uma saída para esta situação. A saída foi bibliotecas de elementos especializadas. Um dos meus favoritos é a maravilhosa biblioteca React Native Web . Ele não apenas cuida das primitivas básicas do aplicativo, permitindo o uso de componentes do React Native na Web (nem todos os componentes!), Mas também fornece acesso a várias APIs do React Native. Entre eles estão Geolocation , Platform , Animated , AsyncStorage e muitos outros. Veja os ótimos exemplos que podem ser encontrados no manual desta biblioteca.

Padrão


Nós descobrimos as primitivas. Mas ainda precisamos conectar o ambiente para desenvolvimento web e desenvolvimento nativo. Meu projeto usa create-react-app (para um aplicativo Web) e um script de inicialização React Native (para um aplicativo nativo, sem Expo). Primeiro, criei um projeto com este comando: create-react-app rnw_web . Em seguida, ele criou um segundo projeto: react-native init raw_native . Depois, seguindo o exemplo de Victor Frankenstein, peguei os arquivos package.json desses dois projetos e os mesclamos. Depois disso, na pasta do novo projeto, alimentei o novo arquivo de yarn . Aqui está o arquivo do package em questão:

 { "name": "rnw_boilerplate", "version": "0.1.0", "private": true, "dependencies": {   "react": "^16.5.1",   "react-art": "^16.5.1",   "react-dom": "^16.5.1",   "react-native": "0.56.0",   "react-native-web": "^0.9.0",   "react-navigation": "^2.17.0",   "react-router-dom": "^4.3.1",   "react-router-modal": "^1.4.2" }, "devDependencies": {   "babel-jest": "^23.4.0",   "babel-preset-react-native": "^5",   "jest": "^23.4.1",   "react-scripts": "1.1.5",   "react-test-renderer": "^16.3.1" }, "scripts": {   "start": "node node_modules/react-native/local-cli/cli.js start",   "test": "jest",   "start-ios": "react-native run-ios",   "start-web": "react-scripts start",   "build": "react-scripts build",   "test-web": "react-scripts test --env=jsdom",   "eject-web": "react-scripts eject" } } 

Observe que não há recursos de navegação nesta versão do arquivo. Em seguida, você precisa copiar todos os arquivos de origem das pastas do aplicativo Web e do aplicativo nativo para a pasta do novo projeto unificado.


Pastas a serem copiadas para um novo projeto

Agora, na pasta src , que fica no diretório do novo projeto, crie dois arquivos: App.js e App.native.js . Graças ao webpack, podemos usar extensões de nome de arquivo para informar ao bundler onde quais arquivos usar. A separação de arquivos de App é vital, pois vamos usar abordagens diferentes para navegar pelos aplicativos.

Aqui está o arquivo App.js para a web. react-router usado para navegação.

 // App.js - WEB import React, { Component } from "react"; import { View } from "react-native"; import WebRoutesGenerator from "./NativeWebRouteWrapper/index"; import { ModalContainer } from "react-router-modal"; import HomeScreen from "./HomeScreen"; import TopNav from "./TopNav"; import SecondScreen from "./SecondScreen"; import UserScreen from "./UserScreen"; import DasModalScreen from "./DasModalScreen"; const routeMap = { Home: {   component: HomeScreen,   path: "/",   exact: true }, Second: {   component: SecondScreen,   path: "/second" }, User: {   component: UserScreen,   path: "/user/:name?",   exact: true }, DasModal: {   component: DasModalScreen,   path: "*/dasmodal",   modal: true } }; class App extends Component { render() {   return (     <View>       <TopNav />       {WebRoutesGenerator({ routeMap })}       <ModalContainer />     </View>   ); } } export default App; 

Aqui está o App.js para o aplicativo React Native. Aqui react-navigation usada react-navigation .

 // App.js - React Native import React, { Component } from "react"; import { createStackNavigator, createBottomTabNavigator } from "react-navigation"; import HomeScreen from "./HomeScreen"; import DasModalScreen from "./DasModalScreen"; import SecondScreen from "./SecondScreen"; import UserScreen from "./UserScreen"; const HomeStack = createStackNavigator({ Home: { screen: HomeScreen, navigationOptions: { title: "Home" } } }); const SecondStack = createStackNavigator({ Second: { screen: SecondScreen, navigationOptions: { title: "Second" } }, User: { screen: UserScreen, navigationOptions: { title: "User" } } }); const TabNav = createBottomTabNavigator({ Home: HomeStack, SecondStack: SecondStack }); const RootStack = createStackNavigator( {   Main: TabNav,   DasModal: DasModalScreen }, {   mode: "modal",   headerMode: "none" } ); class App extends Component { render() {   return <RootStack />; } } export default App; 

Foi assim que criei um modelo de aplicativo simples e preparei a plataforma para trabalhos futuros. Você pode experimentar este modelo olhando para este repositório.

Agora vamos complicar um pouco esse modelo, adicionar um sistema de roteamento / navegação.

Problemas de navegação e suas soluções


Um aplicativo, a menos que consista em uma única tela, precisa de algum tipo de sistema de navegação. Agora (estamos falando de setembro de 2018), existe apenas um sistema de trabalho universal, adequado para aplicativos da web e nativos. É sobre o roteador React . Para a web, essa solução funciona bem, mas no caso dos projetos React Native, nem tudo é tão claro.

No React Router Native, não há transições entre telas, não há suporte para o botão Voltar (para a plataforma Android), não há telas modais, barras de navegação e outros recursos. Outras ferramentas de navegação, como React Navigation , possuem esses recursos.

Eu usei essa biblioteca em particular, mas você pode pegar outra coisa. Portanto, no meu projeto, o React Router é responsável pela navegação no aplicativo Web e o React Navigation pela navegação no aplicativo nativo. Isso, no entanto, cria um novo problema. O fato é que as abordagens para a navegação e a transferência de parâmetros nesses sistemas são muito diferentes.

Para preservar o espírito do React Native Web, usando em todos os lugares uma abordagem semelhante à usada em aplicativos nativos, aproximei-me da solução desse problema criando rotas da Web e agrupando-as no HOC. Isso me deu a oportunidade de criar uma API que se parece com o React Navigation.

Essa abordagem me permitiu percorrer as telas de um aplicativo Web, eliminando a necessidade de criar componentes separados para dois tipos de aplicativos.

A primeira etapa na implementação desse mecanismo é criar um objeto com uma descrição das rotas para o aplicativo Web:

 import WebRoutesGenerator from "./NativeWebRouteWrapper"; //   ,    React Router     HOC const routeMap = { Home: {   screen: HomeScreen,   path: '/',   exact: true }, Menu: {   screen: MenuScreen,   path: '/menu/sectionIndex?' } } //  render <View> {WebRoutesGenerator({ routeMap })} </View> 

De fato, aqui está uma cópia da função de criação do React Navigation com a adição de recursos específicos do React Router.

Em seguida, usando minha função auxiliar, crio rotas do react-router e as envolvo no HOC. Isso permite clonar o componente da screen e adicionar navigation às suas propriedades. Essa abordagem imita o comportamento do React Navigation e disponibiliza métodos como navigate() , goBack() , getParam() .

Telas modais


O React Navigation, graças ao createStackNavigator , possibilita que uma determinada página do aplicativo saia de baixo na forma de uma tela modal. Para conseguir isso em um aplicativo Web, tive que usar a biblioteca do React Router Modal . Para trabalhar com a tela modal, primeiro você precisa adicionar a opção apropriada ao objeto routeMap :

 const routeMap = { Modal: {   screen: ModalScreen,   path: '*/modal',   modal: true //    ModalRoute     } } 

Além disso, o componente <ModalContainer /> da biblioteca <ModalContainer /> react-router-modal deve ser adicionado ao layout do aplicativo. A página correspondente será exibida lá.

Navegação entre telas


Graças ao HOC do nosso desenvolvimento (temporariamente esse componente é chamado NativeWebRouteWrapper , e esse é um nome terrível), podemos usar quase o mesmo conjunto de funções que no React Navigation para organizar o movimento entre as páginas na versão web do aplicativo:

 const { product, navigation } = this.props <Button onPress={navigation.navigate('ProductScreen', {id: product.id})} title={`Go to ${product.name}`} /> <Button onPress={navigation.goBack} title="Go Back" /> 

Retorne à tela anterior.


Em React Navigation, você pode voltar para n telas que estão na pilha de navegação. Similar no React Router não está disponível, não há pilha de navegação. Para resolver esse problema, precisamos importar a função pop de nosso próprio design para o código. Ligando para ela, forneceremos vários parâmetros:

 import pop from '/NativeWebRouteWrapper/pop' render() { const { navigation } = this.props return (   <Button     onPress={pop({screen: 'FirstScreen', n: 2, navigation})}     title="Go back two screens"   /> ) } 

Nós descrevemos estes parâmetros:

  • screen - o nome da tela (usada pelo React Router na versão web do aplicativo).
  • n é o número de telas a serem retornadas usando a pilha (usando React Navigation).
  • navigation - um objeto que fornece navegação.

Resultados do trabalho


Se você quiser experimentar a idéia de desenvolver aplicativos universais apresentados aqui, criei dois modelos.

O primeiro é um ambiente limpo e universal para o desenvolvimento de aplicativos da Web e aplicativos nativos.

O segundo é, em essência, o primeiro modelo, que foi expandido devido ao meu sistema para organizar a navegação em torno do aplicativo.

Aqui está um aplicativo de demonstração papu com base nas considerações acima. Está cheio de erros e becos sem saída, mas você pode montá-lo você mesmo, executá-lo em um navegador e em um dispositivo móvel e, na prática, ter uma idéia de como tudo funciona.

Sumário


A comunidade de desenvolvedores do React, é claro, precisa de uma biblioteca universal para organizar a navegação de aplicativos, pois isso simplificará o desenvolvimento de projetos como o de que falamos. Seria muito bom se a biblioteca do React Navigation funcionasse na Web (na verdade, esse recurso já está disponível , mas trabalhar com ele não é sem dificuldades).

Caros leitores! Você aproveita o React para criar aplicativos universais?

Source: https://habr.com/ru/post/pt428568/


All Articles