Notas do freelancer: Desenvolvendo o primeiro aplicativo nativo do React

O autor do material, cuja tradução publicamos, lançou recentemente seu primeiro aplicativo móvel, escrito em React Native. Aconteceu que esse aplicativo também foi seu primeiro projeto, que ele criou como programador freelancer. Aqui ele vai falar sobre o que ele teve que enfrentar durante o trabalho - desde a inicialização do projeto até sua publicação na App Store e no Google Play.



Por que eu escolhi freelancer?


Em maio passado, desenvolvi um maravilhoso projeto freelancer. Naquela época, eu era desenvolvedor full-stack em uma startup em Estocolmo. Este foi meu primeiro trabalho de programação, cheguei lá há apenas um ano ( aqui falo sobre isso em mais detalhes).

O verão estava se aproximando rapidamente, o ritmo do trabalho, antes daquela loucura, dia após dia, estava ficando mais calmo. Uma vez houve uma semana em que, por ordem de prioridade, tive que lidar com o suporte técnico. Eu tive que lidar com alguns erros, fiquei um pouco entediado, o trabalho não me agradou.

Foi quando eu estava com um humor tão sombrio que meu pai me informou de suas intenções de criar um aplicativo móvel para os clientes de sua empresa. Embora ele soubesse que eu estava muito ocupado no trabalho e não esperava que eu desse todo o meu tempo para implementar sua ideia, ele ainda perguntou se eu gostaria de me tornar algum tipo de consultor nesse novo projeto. Senti então que estava com fome de um trabalho mental interessante e, portanto, respondi sua pergunta positivamente. Embora eu não tenha planejado isso inicialmente, o consultor, como resultado, me tornei um desenvolvedor de aplicativos líder.

Aqui você pode se perguntar por que alguém pode tentar desenvolver desenvolvimento móvel depois de não ter trabalhado como desenvolvedor web profissional por um ano? Não seria mais sensato continuar a ganhar experiência em um nicho escolhido, crescer profissionalmente e criar um currículo impressionante?

Concordo plenamente que isso seria muito mais razoável. Mas sou um "trabalhador de várias estações" sem esperança que decidiu há vários anos tomar decisões de carreira com base não em uma certa estratégia, mas em minhas próprias preferências. Eu decidi fazer o que me traz alegria. Em outras palavras, meu currículo agora parece que dificilmente pode ser levado a um estado ainda mais errático.

Obviamente, fazer o que você gosta e seguir uma estratégia de carreira não é necessariamente um fenômeno mutuamente exclusivo. Na verdade, gostei muito do meu trabalho anterior e do empregador. Aconteceu que me deparei com outro projeto, cujo desejo acabou sendo mais forte do que o desejo de fazer o que estava fazendo antes.

O que tornou esse projeto tão atraente para mim? O que o tornou mais interessante do que trabalhar em um produto de rápido desenvolvimento usado por milhares de empresas, como parte de uma equipe composta pelas melhores pessoas que conheci? Esta pergunta pode ser respondida desta maneira: isso é liberdade, esse é o desafio que me deu a necessidade de resolver um problema difícil e esse é o desejo de autodesenvolvimento.

Por que foi decidido usar o React Native?


Quando entrei no projeto, meu cliente já havia recebido várias ofertas de agências digitais locais. Mesmo antes de considerar a possibilidade de desenvolver o aplicativo de forma independente, fui solicitado de maneira amigável a avaliar essas propostas. Quando olhei para eles, fiquei simplesmente espantado com a baixa qualidade deles.

Uma das agências enviou um esboço do design do aplicativo, que, além de parecer desarrumado, também não correspondia à identidade corporativa refletida no site do cliente. Outro sugeriu preços altíssimos - tanto para o desenvolvimento quanto para o suporte ao projeto. O terceiro, ao que parece, enviou a proposta, mesmo sem ter realmente estudado os requisitos do cliente. Todas as agências que enviaram as propostas tinham uma coisa em comum: criariam um aplicativo usando a estrutura híbrida Cordova.

Mas isso não é tudo. Embora o Cordova seja uma ferramenta totalmente gratuita e de código aberto, uma das agências até tentou esconder informações sobre qual tecnologia específica ele usa. Em vez disso, os representantes da agência falaram de uma plataforma de desenvolvimento de aplicativos móveis "interna" criada internamente. Parece que estávamos conversando sobre um pequeno complemento sobre o Cordova, feito apenas para garantir firmemente direitos exclusivos a essa agência para atender ao aplicativo e tornar difícil e cara a possível transição futura do cliente para outro desenvolvedor. Em geral, as propostas em questão não eram particularmente impressionantes.

Note-se que não tenho nada contra estruturas híbridas. Eu constantemente uso aplicativos que são baseados neles. Por exemplo, Gmail, Slack, Atom, Figma. No entanto, ouvi falar sobre o React Native por algum tempo, sobre como essa biblioteca permite criar aplicativos móveis de plataforma cruzada usando JavaScript que não eram híbridos!

E agora o que? É necessário, de alguma maneira complicada, oferecer suporte ao iOS e Android ao desenvolver aplicativos JavaScript nativos? Essa pergunta surgiu devido ao fato de que, quando eu estava interessado em tais aplicativos, os aplicativos iOS foram escritos usando Objective-C ou Swift, e Java ou Kotlin foram usados ​​para desenvolver aplicativos Android.

Claro, não há truques especiais aqui. Então eu tinha mais uma pergunta. Como os aplicativos React Native podem ser chamados de aplicativos nativos reais? Se você responder a essa pergunta em poucas palavras, acontece que tudo está na API. Levei mais tempo para entender isso do que gostaria de reconhecer, mas a maneira como os aplicativos React Native, chamados nativos, trabalham com plataformas móveis, não consiste em iniciar o código JavaScript ou compilar esse código em código nativo. O fato é que esses aplicativos executam solicitações de API que exibem componentes nativos usando o Objective-C no iPhone e Java no Android.

Se você deseja obter uma compreensão mais profunda dos conceitos básicos do React Native - eu recomendo esta resposta ao Quora, esta é uma apresentação com o React Conf e este material, que fala sobre o lançamento do React Native.

Embora naquela época eu não soubesse exatamente o que estava acontecendo nas entranhas dos aplicativos React Native, eu sabia que o trabalho desses aplicativos era reduzido à execução do código nativo. Esse foi o meu principal argumento contra a escolha de uma das soluções baseadas em Cordova oferecidas pelas agências. Eu pensei que, se uma empresa precisa de um aplicativo móvel, esse aplicativo deve ser nativo. Se alguém precisar de um aplicativo criado com base em HTML / CSS / JS, seria melhor gastar o dinheiro simplesmente para melhorar os recursos móveis de seu aplicativo da web.

Quando compartilhei esse raciocínio com um cliente, ele me fez uma pergunta sobre se conheço alguém que possa criar um aplicativo assim. Eu respondi que não sabia. Então eles me perguntaram se eu poderia fazer isso sozinho. "Eu não posso", respondi. No entanto, naquela época, eu já estava interessado em tudo isso e simplesmente não podia deixar de experimentar o React Native, tomando as especificações do aplicativo como base dos meus experimentos.

Antes de me dar conta disso, pude criar a base para o aplicativo. Como resultado, apenas algumas semanas após a conversa, o cliente e eu concordamos em desenvolver o aplicativo para ele.

Especificações de aplicação


Antes de nos aprofundarmos nos detalhes técnicos, quero falar um pouco sobre que tipo de aplicativo estamos lidando.

O cliente para quem o aplicativo é desenvolvido é uma empresa em Estocolmo, que se dedica à administração de coworking, escritórios coletivos. Em outras palavras, estamos falando de espaços de escritórios que podem ser alugados por várias empresas. No momento, meu cliente tem cerca de 10 escritórios existentes, nos quais aproximadamente 400 empresas com 1.400 funcionários alugam espaço. Esses são os inquilinos dos escritórios e são o público-alvo do aplicativo.


Área de recreação em um dos coworking

Após discutir a futura aplicação com o gerente do projeto, consegui descobrir alguns requisitos para o projeto:

  • A capacidade de efetuar login, sair e redefinir a senha. Observe que todas as contas de usuário são criadas pelos administradores e o aplicativo não suporta registro no sistema. Portanto, se você decidir baixar este aplicativo, não poderá trabalhar com ele.
  • Ver e editar o perfil do usuário: nome, endereço de email, senha, avatar.
  • Suporte para notificações push.
  • A seção Home, com a qual o usuário pode se familiarizar com as notícias da empresa como um todo e, em particular, com as notícias sobre coworking alugado pela empresa.
  • Seção Comunidade, com a qual o usuário pode visualizar informações sobre vários coworking, entre em contato com seus gerentes e veja quais empresas estão envolvidas em um determinado coworking.
  • Seção Conferência, com a qual você pode reservar salas de reunião e gerenciar reservas.
  • Seleção de Seção, na qual o usuário pode encontrar descontos e ofertas exclusivos.
  • Primeiro, você precisa criar uma versão para iOS e adicionar suporte para Android.
  • Aplicativo baseado na Web para o administrador, que permite gerenciar as informações exibidas no aplicativo React Native. Embora aqui falemos principalmente sobre desenvolvimento front-end, acho que seria apropriado mencionar que a parte do servidor do aplicativo para administrador é baseada em Ruby on Rails, Postgres e Heroku.

Você pode perceber que este projeto possui requisitos bastante modestos. Talvez algo nesse espírito possa ser chamado de bom exemplo da primeira aplicação que alguém desenvolverá usando um novo conjunto de tecnologias. Se você estiver interessado em dar uma olhada no que eu acabei (e, de passagem, decidir gastar algum tempo lendo a história sobre como exatamente tudo isso funcionou para mim), aqui está uma visão geral da primeira versão do aplicativo.


Primeira versão do aplicativo

Ainda está lendo? Ótimo, então vamos seguir em frente.

Aprendendo com os melhores


Imagine que você prometeu a seus amigos a construção de uma casa para eles. Mas você não sabe como fazê-lo. Você nem sabe por onde começar. O que deve ser feito primeiro em tal situação? A resposta é óbvia: encontre alguém que possa construir casas e aprenda com ele.

A rigor, é exatamente isso que tentei fazer. E tive muita sorte de encontrar exatamente o que você precisa. Portanto, depois de apenas algumas horas pesquisando materiais de treinamento do React Native, encontrei no YouTube um curso em vídeo de 13 partes do Harvard React Native. Cada palestra com duração de 90 a 120 minutos foi dedicada a um tópico separado. Como resultado, fui confrontado com cerca de 23 horas de materiais de treinamento de alta qualidade.

Tendo encontrado esse curso, imediatamente, como um obcecado, comecei a estudar. Como resultado, após várias semanas de aulas nas quais eu poderia passar as noites e os fins de semana, terminei este curso e criei uma boa base para a aplicação.

Agora posso dizer que esse curso, sem dúvida, é o melhor que consegui encontrar. Classes concisas e bem preparadas, é claro, tiveram um papel muito positivo na escola, mas não posso deixar de notar a habilidade do professor. Eu descreveria o estilo de conduzir essas aulas com as seguintes palavras: velocidade, extrema praticidade, foco. Sem água, sem piadas irrelevantes ou histórias da vida. Ao contrário do que seu humilde servo escreve aqui ...

De uma maneira ou de outra, havia a sensação de que tantas informações úteis eram colocadas em cada palestra que levaria o dobro do tempo para apresentá-las a muitos outros professores. Em outras palavras, este curso é muito semelhante ao conhecido Harvard CS50.

Como resultado, se você deseja encontrar uma base para o seu primeiro aplicativo React Native, eu definitivamente recomendo este curso para você. Embora aqui se deva notar uma característica. Esse curso usa o kit de ferramentas da Expo . Essa é uma excelente ferramenta adequada para a maioria dos aplicativos simples, que assume todos os tipos de sutilezas em relação ao trabalho com plataformas móveis. Mas se você, como eu, deseja criar a base para um projeto que, mais cedo ou mais tarde, pode se transformar em um aplicativo grande e complexo, e você, ao mesmo tempo, deseja total liberdade de ação, provavelmente é melhor inicializar o projeto Reagir nativo.

O segundo "recurso de treinamento" que eu poderia usar foram meus colegas. Felizmente, a empresa em que trabalhei também começou a desenvolver o projeto React Native. Embora eu próprio não estivesse envolvido nesse projeto, aprendi muito, apenas conversando com aqueles que trabalharam nesse projeto e analisando seu código.

Agora que discutimos tudo o que ocorre com o desenvolvimento de aplicativos React Native, é hora de passarmos para problemas técnicos.

Ambiente de desenvolvimento


Depois de usar uma equipe do formulário react-native init MyApp , criei a base do aplicativo, uma das primeiras tarefas que me confrontaram foi o desenvolvimento de um novo ambiente de desenvolvimento.

Se você veio para o ambiente React Native a partir do desenvolvimento habitual da Web, deve-se notar que muito aqui lhe parecerá familiar. Para mim, isso significava que continuava usando o Atom como editor de código, o iTerm como terminal e o GitUp como interface para trabalhar com o git. (Se os fãs do Vim estão lendo isso agora, sugiro que todos não fiquem convencidos.) Mas, além das ferramentas acima, eu precisava de algo mais para desenvolver aplicativos React Native.

Por exemplo, eu precisava me acostumar com o emulador do iOS. Embora a execução, por ferramentas de linha de comando, do comando react-native run-ios , pareça enganosamente simples, no início de uma simples chamada para esse comando não foi suficiente para o emulador funcionar corretamente. Como novos pacotes npm foram adicionados ao projeto quase diariamente (e mais tarde, alguns módulos nativos do CocoaPod), eu, muito mais perto do que gostaria, fui forçado a familiarizar-me com o ritual desagradável de limpar os recursos do Watchman e o cache do Haste, excluindo a pasta node_modules, reinstalar módulos e redefinir o cache do Metro Bundler. Felizmente, todas essas tarefas podem ser resolvidas usando o seguinte comando:

 watchman watch-del-all && rm -rf tmp/haste-map-react-native-packager && rm -rf node_modules && yarn && npm start --reset-cache 

Em 9 dos 10 casos, uma "dança com pandeiro" permitiu ao emulador voltar à vida. Às vezes, porém, nem isso era suficiente. Então eu tive que me aprofundar na descrição das mensagens de erro no GitHub e ler as discussões no StackOverflow.

A raiz de alguns outros problemas foi o fato de, durante muito tempo, pensar que, para resolver alguns problemas, era necessário executar o Xcode. E acredite, você se esforçará para permanecer nesta IDE de terror house o menos tempo possível.

Uma história semelhante foi com o lançamento do emulador com uma certa versão do iPhone. Se alguém tivesse me dito anteriormente que o comando abaixo resolve esse problema diretamente da linha de comando, talvez eu tenha vivido um pouco mais fácil nos meus primeiros meses de desenvolvimento do React.

 react-native run-ios --simulator='iPhone X' 

Outros exemplos das dificuldades de se acostumar com o novo ambiente de desenvolvimento incluem o processo de três etapas de preparação da versão do aplicativo (para colocação na App Store ou em algum ambiente de integração contínua, como o Visual Studio App Center ou Firebase) e o processo de transição da versão para a versão, destinado à depuração (para o modo de desenvolvimento). Talvez muitos achem óbvio que as alterações necessárias no projeto podem ser feitas usando qualquer editor de texto. De qualquer forma, este é apenas um exemplo de algumas pequenas coisas que tiveram um impacto inesperadamente grande no meu fluxo de trabalho ao trabalhar no modo de desenvolvimento.

E, finalmente, levou algum tempo para me acostumar com a necessidade de alternar constantemente entre os vários aplicativos do macOS necessários para resolver as tarefas que eu, ao desenvolver aplicativos da Web, geralmente resolvia usando o Chrome sozinho.

Para observar o que o código JavaScript está gravando no console e analisar, para fins de depuração, a saída HTML / CSS, virei-me para o React Native Debugger . Para monitorar o status do aplicativo, as ações enviadas, as solicitações de API e as respostas recebidas, usei o Reactotron . Embora eu ache esses dois aplicativos extremamente úteis, não pude deixar de pensar no meu fluxo de trabalho habitual usado para criar aplicativos Ember.js, quando consegui resolver todas essas tarefas no mesmo ambiente em que meus aplicativos foram executados (usando o plug-in Inspetor de brasas para Chrome).

Navegação


Organizar a navegação / roteamento parece ser uma tarefa muito difícil para o React Native. Durante a existência dessa estrutura, muitas soluções diferentes para esse problema surgiram, mas ainda há algo que poderia ser chamado de padrão universalmente reconhecido. Decidi usar a biblioteca de navegação de reação, minha escolha foi influenciada principalmente pelo fato de eles falarem sobre essa biblioteca no curso React Native que eu participei, bem como pelo fato de meus colegas a usarem.

Se eu investisse algum tempo em um estudo suficientemente profundo dessa questão, poderia descobrir o seguinte:

  • O projeto de navegação e reação possui aproximadamente 15.000 estrelas no GitHub e 86 questões não resolvidas. É inteiramente baseado em JavaScript e apresenta a documentação mais detalhada entre as soluções de navegação que eu já vi.
  • A biblioteca de navegação react-native-score obteve cerca de 10.000 estrelas, resultando em 162 problemas não resolvidos. No entanto, ele usa não apenas JavaScript. Para trabalhar com isso, você precisa editar arquivos nativos.
  • O repositório react-router possui aproximadamente 35.000 estrelas e uma lista de 55 questões pendentes no GitHub. É verdade que esses indicadores não podem ser comparados diretamente com os outros projetos descritos aqui, pois esse repositório inclui pacotes projetados não apenas para o React Native, mas também para o React.
  • O projeto de navegação nativa tem cerca de 3.000 estrelas e 55 problemas não resolvidos. Quem vai estudá-lo e usá-lo deve considerar que ele ainda está na versão beta, que usa não apenas JavaScript e é suportado pelo Airbnb (essa empresa decidiu abandonar o React Native )

Mas, mesmo considerando o exposto, provavelmente teria escolhido a navegação de reação de qualquer maneira, já que não tive tempo de experimentar todas essas bibliotecas, como, por exemplo, o autor deste relatório. E, finalmente, como foi dito neste relatório, a escolha de uma ferramenta para organizar a navegação é uma pergunta cuja solução não depende de qual dessas ferramentas pode ser considerada a melhor, mas de qual delas é mais adequada às necessidades de um projeto em particular.

Depois de trabalhar com o react-navigation por cerca de 9 meses, devo dizer que realmente não tenho do que reclamar. Se você comparar esta biblioteca com a biblioteca familiar router.js usada no Ember.js , posso dizer que isso é algo completamente novo.

Foi realmente fácil para mim lidar com os três principais tipos de ferramentas de navegação de navegação por reação. Estes são StackNavigator , TabNavigator e DrawerNavigator . Era muito mais difícil entender como combinar essas ferramentas para criar o sistema de navegação de aplicativos que eu precisava.

Por exemplo, o fato de o componente DrawerNavigator ser o elemento raiz do sistema de navegação (uma etapa acima do componente principal do TabNavigation ) era completamente óbvio para mim. Se é difícil imaginar, é assim que o DrawerNavigator fica em ação (em um aplicativo real, tudo funciona de maneira muito mais suave).


DrawerNavigator da navegação de reação em ação

Como você pode ver, eu precisava abrir a barra de navegação lateral com um toque, estando em qualquer tela de aplicativo.

Eu percebi a barra lateral como algo secundário em comparação com a barra de navegação principal localizada na parte inferior do aplicativo. Portanto, pareceu-me que o DrawerNavigator deveria ser colocado na árvore de rotas (como mostrado abaixo), sob o BottomTabNavigator principal ou no mesmo nível desse elemento.

No entanto, depois de sofrer muito, tentando forçar a barra lateral no local em que ela se mostrou inadequada, percebi que, de acordo com os recursos da navegação de reação, o DrawerNavigator deve ser colocado um passo acima do BottomTabNavigator , ou seja, em raiz da árvore de navegação. Espero que essa descoberta ajude um dos leitores deste material a economizar tempo que, de outra forma, seria gasto lendo a documentação e os materiais no GitHub.

Veja como é a árvore de navegação do aplicativo. Aqui, como elemento raiz, MainDraverNavigation usado.


A árvore de navegação final da primeira versão do aplicativo

Aqui você pode se perguntar por que, nas seções Comunidade e Conferência, você precisa do StackNavigator e TabNavigator . Você não pode simplesmente soltar a camada StackNavigator e ir direto para o TabNavigator ?

O problema é que eu precisava de cada um dos dois elementos do TabNavigator para ter um título. Aqui estão eles.


TabNavigator, título

Aqui, novamente, minhas suposições não combinavam com o dispositivo de navegação de reação. Eu pensei que o MaterialTopTabNavigator deveria ser um componente de navegação completamente normal, então decidi que deveria haver alguma opção interna em suas configurações que permita definir um título. Como se viu, não havia nada disso, e é por isso que eu tive que usar o StackNavigator como uma camada intermediária, adicionando, como resultado, um nível adicional de complexidade à infraestrutura do aplicativo e sendo orientado por considerações "cosméticas".

Além disso, essa falta de navegação de reação me causou problemas muito mais sérios. Em particular, eles consistiam na necessidade de organizar a dobra e o desaparecimento da imagem do cabeçalho durante a rolagem do usuário pela lista de elementos organizados pelo FlatList . Como os títulos das seções Início e Seleção foram exibidos no mesmo StackNavigator que as listas de seus elementos, esse problema não seria difícil de resolver, basta deixar o título rolar junto com o restante da lista.

Porém, no caso das seções Comunidade e Conferência, não consegui encontrar uma maneira de aplicar a mesma solução, pois os cabeçalhos são exibidos usando os elementos StackNavigator e as listas são exibidas usando os elementos StackNavigator , um passo acima na árvore de navegação. Como resultado, recusei-me a rolar o título, o que introduziu uma heterogeneidade desagradável no aplicativo.


Rolagem no TabNavigator e StackNavigator

Embora o problema descrito com o título no simulador do Iphone X não pareça sério, na tela pequena, o título pode ocupar cerca de 20% do espaço disponível na tela. Se alguém souber como resolver esse problema, me avise.

O mesmo problema com o TabNavigator também foi sentido na seção Destino. Como será mostrado na figura a seguir, à direita, eu queria colocar outro elemento do TabNavigator na guia Espaços de Coworking para exibir as três principais guias Informações, Membros e Contato.

Ao trabalhar com o TabNavigator era difícil colocar uma apresentação de slides na parte superior do elemento sem ter que complicar a decisão e não causar muitos problemas de navegação (principalmente relacionados às opções de navegação). Então, tive que recorrer a um pacote JS chamado react-native-swiper para trabalhar com essas três guias. Note-se que esta solução seria totalmente adequada para mim se sua aplicação não levasse a uma animação abrupta de linhas que enfatizassem os cabeçalhos das guias. De qualquer forma, considerei essa desvantagem um pagamento justo pela oportunidade de evitar problemas com um sistema de navegação alternativo.


Compare o TabNavigator da react-navigation com o react-native-swiper (observe a diferença na animação das linhas douradas abaixo dos nomes das guias)

Aqui estão as conclusões que tirei depois de implementar o subsistema de navegação do aplicativo:

  • Existem muitas soluções bem documentadas para organizar a navegação nos aplicativos React Native, entre as quais eu escolhi a navegação de reação. É mais adequado às minhas necessidades.
  • A biblioteca de navegação de reação simplifica bastante o início do trabalho em um projeto se o desenvolvedor não souber muito sobre como os sistemas de navegação das plataformas móveis funcionam.
  • A biblioteca de navegação de reação possui alguns recursos que não são intuitivos (pelo menos para um desenvolvedor da Web), mas não há nada que não possa ser contornado, embora não da maneira mais eficiente.

Tela inicial


Ao iniciar um novo aplicativo no emulador criado por meio do comando react-native init , recarregando-o constantemente à medida que você faz alterações, você rapidamente percebe que o aplicativo precisa de uma boa tela inicial (elas também são chamadas de "telas iniciais").

Como fazer uma tela inicial está bem escrito aqui , então não repetirei as palavras do autor deste material. Vou falar apenas sobre o problema que encontrei e sobre o qual não há nada neste guia. Aqui está a aparência desse problema:


A tela inicial com um problema

Esse problema aparece em casos raros no iOS, mas alguns usuários do aplicativo provavelmente o encontrarão. Descobri esse problema pela primeira vez quando trabalhava em um lugar, onde não podia usar o Wi-Fi e conectei meu laptop à Internet 4G através de um telefone. Os usuários de iPhone sabem que, quando o telefone distribui a Internet, sua barra de status fica azul e aumenta. Isso "quebrou" a imagem na minha tela inicial quando iniciei o aplicativo no telefone. O mesmo problema surgiu ao ligar.

Como resultado, tendo vasculhado por algum tempo o repositório react-native-splash-screen e não encontrando nada útil lá, decidi contornar esse problema ocultando completamente a barra de status enquanto mostrava a tela inicial.

É muito simples - basta adicionar a chave UIStatusBarHidden ao UIStatusBarHidden , atribuir o valor lógico true e, depois de chamar SplashScreen.hide() , defina a propriedade hidden do componente React Native StatusBar como StatusBar .

Gestão estatal


Tenho a sensação de que, nos últimos dois anos, tenho ouvido todos os dias sobre a prioridade do acordo sobre a configuração, o princípio da Convenção sobre a Configuração (CoC). Então foi no meu trabalho anterior. E isso não é surpreendente, já que, no servidor, usamos o Ruby on Rails e no cliente - Ember.js - duas estruturas, cuja essência corresponde da melhor maneira possível ao princípio CoC. Eu pensei que sabia o que isso significava, mas o processo de explorar o gerenciamento de estado no React Native me deu uma nova compreensão desse princípio.

Embora eu, em várias aplicações muito simples, tenha experimentado a biblioteca React influenciada por esse princípio, nunca criei algo grande o suficiente com base nela que me permitisse apreciar as vantagens de usar contêineres de estado como Redux ou MobX . A maior parte da minha experiência no gerenciamento do estado dos aplicativos JS é com o Ember Data (este é o sistema interno do Ember para gerenciar o estado e organizar o armazenamento persistente de dados).

Como a biblioteca Redux me pareceu ser uma das melhores soluções para o problema de gerenciamento de estado que eu ouvira falar por muitos anos (e que foi discutido no curso React Native que abordamos), em geral, não olhei para os concorrentes. . Eu só queria equipar meu aplicativo com os melhores sistemas de gerenciamento de estado existentes e fazê-lo sem muito esforço.

No Ember, 90% da infraestrutura de dados está nas mãos do programador pronto para uso. Eu não suspeitava que no meu projeto atual tudo será exatamente o oposto. Como se viu, não apenas o React, mas o Redux, a biblioteca de gerenciamento de estado mais popular, não oferecem nada útil para manter o estado global. Essa biblioteca é tão leve que o programador precisa enfrentar 90% das preocupações com o trabalho com dados dentro do aplicativo para criar um sistema de gerenciamento de estado decente.

Depois que eu, um desenvolvedor muito menos experiente do que agora, descobri, a coisa mais difícil para mim foi me acostumar com a nova funcionalidade e os princípios da imunidade. Depois que eu aguentei a quantidade surpreendentemente grande de trabalho que precisa ser feita para simplesmente baixar dados do servidor ou enviá-los ao servidor, tudo isso se reuniu na forma de 7 etapas bastante simples:

  1. Adicione três constantes ao arquivo com constantes: SOME_ACTION_REQUEST , SOME_ACTION_FAILED , SOME_ACTION_SUCCEEDED .
  2. Adicione o criador da ação ao arquivo de ação.
  3. Processe três ações em um redutor adequado e, se necessário, adicione um novo redutor ao sistema e inclua-o no redutor raiz.
  4. Adicione trabalhadores a uma saga adequada e, se necessário, adicione uma nova saga ao sistema e inclua-a na saga raiz (eu uso a biblioteca redux-saga para processar ações assíncronas).
  5. Adicione uma função para manipular quaisquer solicitações de API possíveis.
  6. Mapeie os dados necessários do estado para as propriedades no componente React correspondente.
  7. Envie a ação SOME_ACTION_REQUEST do componente React correspondente.

Redux e redux-saga, é claro, têm recursos muito mais abrangentes, mas considerando o que me interessa atualmente, os 7 passos acima são o que Redux é para mim.

Sessões


Então, configuramos o ambiente de desenvolvimento para aplicativos React Native, criamos uma árvore de navegação, preparamos a infraestrutura de gerenciamento de estado. O que será bom fazer na próxima etapa do projeto? Para mim, a criação de um sistema de autenticação de usuário foi uma resposta completamente natural a essa pergunta. Então agora vamos falar sobre sessões.

Se você veio para a esfera React Native a partir do desenvolvimento da Web, lidará com as sessões sem muita dificuldade. Se você estiver um pouco familiarizado com os conceitos nos quais o armazenamento LocalStorage se baseia , precisará saber apenas que, ao trabalhar com o React Native, o acesso a esse armazenamento deve ser substituído por uma chamada para AsyncStorage . Esse é o nível de abstração que permite armazenar dados no formato de valor-chave entre as sessões. Em outras palavras, aqui você pode armazenar o token de autenticação gerado no servidor, transmitido ao cliente depois que o usuário efetua login no sistema.

Listas


Se falamos sobre trabalhar com listas, tive a sensação de que no React Native esse problema foi resolvido muito bem. Em geral, pode-se notar que o desenvolvedor tem três possibilidades. Se funcionar com listas estáticas, cujos dados não são alterados, o ScrollView provavelmente terá o suficiente.Se você precisar trabalhar com listas mais longas, que são dinâmicas, vale a pena examinar o FlatList . Se estivermos falando de listas ainda maiores, que também podem ser divididas em seções, será útil recorrer ao SectionList .

Eu, para listas dinâmicas, uso exclusivamente FlatList. E embora eu, em um nível intuitivo, como essas listas e a capacidade de configurá-las, eu, ao trabalhar com elas, encontrei vários problemas. Agora vou falar sobre eles.

▍Desenhe a lista para atualizar seu conteúdo


FlatList , refreshControl . , , , , . , React Native , . — RefreshControl . , .


RefreshControl

, , , refreshControl , RefreshControl , , . , , :

  • , , . , handleRefresh() .
  • , , « » ( ).

— .

, , , , . , , , GitHub.

, refreshControl onEndReached ( ) fetching . , - , false true , — , , 250 , RefreshControl , .

, setTimeout() fetching 350 . . , , setTimeout — , , handleRefresh() handleLoadMore()refreshing loadingMore . , , , , - .

, onRefresh refreshing refreshControl . , refreshControl , , , , .


, . — , , Load More , , , , .


FlatList. , , 2, onEndReached , 2-

, onEndReached . .

onEndReachedThreshold , FlatList , , onEndReached . .

100 , , 10 , 1, onEndReachedThreshold , , onEndReached , , 90-. 2, , 2- , — 80- , .

, , , , FlatList . , , , , handleLoadMore() , onEndReached , , — 10 .

, , loadingMore , , handleLoadMore() , , , !loadingMore . , , .


ListLoadingComponent FlatList , , ListHeaderComponent , ListEmptyComponent ListFooterComponent , , - , , , .

, render() .


, , , . , , .

, scrollToOffset FlatList , , . , . ref FlatList :

 <FlatList ref={(ref) => { this.newsListRef = ref; }} ... /> 

, . ScrollToOffset handleScrollToTop() , , , react-navigation, , :

 componentDidMount() { this.props.navigation.setParams({   scrollToTop: this.handleScrollToTop, }); } handleScrollToTop = () => { this.newsListRef.ScrollToOffset({   x: 0, y: 0, animated: true, }); }; 

, react-navigation 3 ref , BottomTabNavigator .


, , . , , 4G- ( , , 3G), , , , , .

, , , , , , , . . , , , , .

, , . 7 , image , , ( , ).


, , . react-native-image-picker , Cloudinary Carrierwawe Rails-.

, Node-API Cloudinary react-native-fetch-blob . , , , , , .

, , react-native-fetch-blob, . , react-native-fetch-blob , API JS FormData . , react-native-fetch-blob rn-fetch-blob , .


, React Native Image style , source resizeMode . , , - , , , .

, , , . , , , . . Avatar react-native-elements.

, Image . , - , .

, , . .


react-native-slideshow

react-native-slideshow , , . , , , , , , .


7 , , . , — , , . , - . .

, , -, , , , - ( — ), , , , Facebook . , .

, , React Native-. , . — react-native-loading-placeholder , , , . — react-native-linear-gradient , . , , , , , , , , .


react-native-loading-placeholder react-native-linear-gradient


— . , React Native Image . , - CachedImage react-native-cached-image .

npm- Image , , , CachedImage . Reactotron , , .

, , , . , , Cloudinary, 95% , , 4%. .

, . CachedImage activityIndicatorProps={{ animating: false }} , .



React Native - Picker . - , ( - ), JS-, . , react-native-picker-select , <select> iOS Android .

JS-, React Native- ( lodash , ), , , , . , , - . , .


react-native-calendars Wix. :

  • iOS , . , , , -, — .
  • React Native — DatePickerIOS DatePickerAndroid , , .
  • , , , Apple Google.

, . , , — .


react-native-calendars react-native-picker-select


— , .
SaaS-, . SOAP, API Conference. , , , , .

, , , 5 . - , JavaScript Date UTC, , . , , , , , - . « », — .

, , moment-js , React Native, timezone , :

 const timeSthlmAfterFive = moment().isAfter(moment.tz('17:00:00', 'HH:mm:ss', 'Europe/Stockholm'), 'second'); 


, , , . React Native -, , , , , , font-face CSS.

. , . , 10 -. react-native-vector-icons .

, ,


CI/CD, DevOps- -, .

( ) , - . , . GitHub- . , :

  • . , , .
  • , - , , .

. , , , , , , push-. , , , , .

Visual Studio App Center (VSAC). Chain React 2017 . , , , DevOps-, . , , , , push-, Codepush . -. , , , , iOS, Android. , - , , , , , - .


Visual Studio App Center ( )

« », — , . , (API — ). , , , , -, (, , ).

? Microsoft, , VSAC « ». , , Codepush ( React Native-) HockeyApp ( ), - . , «developers, developers, developers, developers» .

, VSAC , - Fastlane , BuddyBuild Firebase ? , , , VSAC , , , . , , ? , VSAC, , .

VSAC. , , , .

, , , VSAC Apple Developers (Apple, , , ). , , , .

, VSAC, , , CI/CD- .

Android


, iOS- , Android . Android Studio Android React Native Platform . , Platform.select() . - , , , Platform.OS .

, , Google Play , App Store. Porque , App Store Apple.

Apple


, -, React Native, . , Apple. , , , , , .


Apple

, — « ». -, , iOS-, , , , .

— Apple. , , , . Dun & Bradstreet, Apple, . , , , Apple (, , Apple , — ).

, Apple , , — , -. . , — ?

, .

, , Apple Developer . .

. . provisioning-, iOS-, , Apple .p12 push-, dSym-. , , , .

Apple, 50% 24 , 90% — 48 . , , — , , Apple-.

, . «Metadata Rejected». , - . , 5 ( App Store Review Guidelines ), .

, , , — . , , , , , . , — , () .

iOS, . , , , . , , . . , , .

Sumário


, React Native- . React Native-. -. , : . .

, , , , . , , — , .

, - , . . , , , 8 . . .

, . , , - .

, , , 6-7 , . , , , :

  • , (iOS Android), , , .
  • JavaScript. , , Ember.js.
  • React.js, , React-, . , JS-/.
  • , Redux.
  • DevOps .
  • , .
  • UI/UX.
  • , , , , , , , , .

JS- , Flutter , NativeScript , Objective-C, Swift, Java Kotlin, React Native .

, -, , React Native , , , . , React Native — , . React Native .

Caros leitores! ?

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


All Articles