parque@superaparque.com.br

+55 16 3315 - 0303

+55 16 3315 - 0735

O Guia Definitivo de Modais no React Native

React Native é um framework para desenvolvimento de aplicativos com Javascript. Esse é um artigo focado em desenvolvedores já familiares com a tecnologia, que desejam se expor a conceitos mais complexos e descobrir soluções novas para problemas do dia-a-dia, como Modais.

Você já percebeu que utilizar modais no React Native pode ser um pouco chato? Pois é, manter vários estados de “aberto” e “fechado”, tendo que repetir o código em sempre que o modal aparece em um lugar novo não é nem um pouco legal e nem eficiente.

Esse problema piora bastante quando você tenta criar fluxos complexos. Uma vez que você passa de dois modais na mesma tela, seu componente principal se torna uma bagunça, e os estados crescem exponencialmente.

Eu passei por isso na prática em muitas empresas, como no Zé Delivery, no Alfred Delivery e agora na X-Team.

Mas relaxa, é normal! Todo mundo faz assim. Certo? Bom, não exatamente.

Neste artigo, vou te explicar como uma simples tarefa pode gerar um código dificil de manter. Também vou dar um passo a passo de como resolver esse problema de uma forma inteligente, melhorando a sua experiência de desenvolvimento. De quebra, ainda te ensino como chamar modais fora de componentes React (em Sagas, por exemplo!)

Os ensinamentos deste artigo foram encapsulados, na prática, nessa lib:

Os Desafios de um Fluxo “simples”

Imagine esse cenário: Você trabalha no Facebook e a Equipe de Produto pede um fluxo “simples”:

Como empresa, gostaria de mostrar um modal solicitando que o usuário avalie o aplicativo entre 0 e 5 estrelas depois que o usuário curtir um post pela primeira vez.

a. Se o usuário avaliar com menos de quatro estrelas, mostre outro modal pedindo feedback sobre como melhorar.

b. Caso contrário, mostre um modal comemorando e pedindo para que o usuário nos avalie na App Store.

No final, independente da resposta, mostre um modal de agradecimento ao usuário.

Parece um caso bem normal, certo? Mas você consegue identificar como será o código?

Você se vê escrevendo lógicas complexas para lidar com a ordem dos modais, fazendo vários checks para certificar que o modal anterior não esteja mais visível antes de mostrar o próximo, e tendo de usar diversas hooks para controlar o estado? E pior, sem ter certeza de onde essa lógica deve ficar?

O Problema Pode Piorar

Imagine que você finalmente conseguiu, terminou o fluxo e a equipe de produto amou o resultado! Eles agora querem expandir esse fluxo para mostrar apenas uma vez sempre que o usuário curtir algo pela primeira vez, seja um post, um comentário ou um produto. Como você abordaria isso?

Você teria que copiar e colar todos esses quatro modais em cada tela onde uma curtida é possível. Talvez você até vá em frente e transforme todo esse fluxo em um único componente. Mesmo assim, ainda é necessário adicionar esse novo componente a todas as telas e lidar com no mínimo algum estado.

Alguns meses se passam, e a equipe de desenvolvimento agora vê a complexidade de lidar com curtidas de forma diferente em cada tela. Eles querem passar essa responsabilidade para uma Saga, do Redux, que pode ser chamada de qualquer lugar. Como você mostra o modal apenas quando a Action da Saga é disparada? As Sagas rodam fora dos componentes do React.

Eu posso dizer com confiança que já passei por esses cenários. Trabalhando na indústria de entrega de alimentos, solicitamos constantemente ao usuário que avalie o aplicativo, a entrega e sua compra.

Evitando o Problema

Vamos começar tratando do estado. Gerenciá-lo é uma das coisas mais importantes ao trabalhar com modais.

Exponha Props Internas Com o “useImperativeHandle”

O useImperativeHandle permite expor propriedades internas por meio de uma Ref.

Em um componente de modal, você pode utilizar o useImperativeHandle para expor suas funções ‘show’ e ‘hide’. Assim, ele pode se cuidar do seu próprio estado sem delegar para o seu componente pai com props, separando as responsabilidades.

Exemplo:

Embora seja um passo na direção certa, a hook por si só não resolve todos os nossos problemas. Especificamente:

  • Para usá-lo, precisamos passar uma ‘ref’ vinda do hook ‘useRef’. Como hooks só funcionam em componentes React, isso significa que não podemos chamar o ‘show’ e ‘hide’ em funções externas.
  • Ainda precisamos instanciar o componente em todas as telas. Não temos como utiliza-lo em várias telas sem repetir o ExampleModal.

 

Expondo Externamente a Ref do Componente

A maioria das pessoas não sabe disso, mas o React tem um método chamado ‘createRef’ que pode ser usado fora dos componentes do React.

Ele está até na documentação do React-Navigation para casos não convencionais: https://reactnavigation.org/docs/navigating-without-navigation-prop/

Na prática, a flexibilidade que essa função nos trás pode ser vista aqui:

Agora, o ‘imperativeModalRef’ pode ser importado e usado em qualquer lugar, desde que o SmartExample esteja na raiz. Podemos chamar o ‘show’ e ‘hide’ dentro de componentes, funções e até Sagas.

Isso resolve a maioria dos nossos problemas, mas ainda há um: Pode se tornar difícil e pouco escalável gerenciar um projeto com muitas Refs de modais, e com muitos containers de Modal na raiz do projeto.

Mas, é ai que você pode ser criativo com abstrações para fazer um só container renderizar qualquer modal! Uma maneira de fazer isso é fazer com que a função ‘show’ receba um componente de modal, e renderize só o que foi passado.

Em vez de fazer vocês reinventarem a roda, criei uma biblioteca de código aberto que encapsula todos esses conceitos e muito mais, com suporte completo a TypeScript, baseado no react-native-modal.

Um exemplo básico de como utilizar:

“Talk is cheap. Show me the code.” — Linus Torvalds.

Como você pode ver, esses conceitos juntos oferecem uma flexibilidade antes inimaginável, simplesmente abstraindo algumas funcionalidades básicas.

Agora, o fluxo de confirmação pode ser chamado de qualquer lugar. Dentro ou fora de componentes React.

Além disso, ele lida automaticamente com problemas comuns em relação aos modais, como a concorrência.

Você sabia que, no React Native, você não pode mostrar dois modais simultaneamente?

Mesmo se você tentar mostrar um modal logo após o outro, provavelmente falhará, pois o último modal ainda está animando seu estado ‘fechar’. Felizmente, a questão já é tratada do nosso lado.

https://github.com/react-native-modal/react-native-modal/issues/30

A documentação do React Native Magic Modal é fácil de entender e com certeza vai melhorar sua experiência de desenvolvimento em geral:

 

 

Este artigo foi elaborado pelo convidado Gabriel Sozza Taveira José, Senior Software Engineer da X-Team.

Quer ver seu artigo por aqui? Fale com a gente: caio@skycomunicacao.jor.br

 

 

Quer saber mais sobre startups, empreendedorismo e inovação? Continue acompanhando nosso blog e redes sociais para ter acesso a conteúdos e informações relevantes.