Instalando o Mapbox e listando os imóveis no ReactJS

Série Clone AirBnB com AdonisJS, React Native e ReactJS [Parte 9]

Instalando o Mapbox e listando os imóveis no ReactJS

Esse post é a nona parte da série de posts “Clone AirBnB com AdonisJS, React Native e ReactJS” onde iremos construir do zero uma aplicação web com ReactJS e também uma aplicação mobile com React Native com dados servidos através de uma API REST feita com NodeJS utilizando o framework AdonisJS.

Aqui estamos em mais um post dessa série sensacional, nesse ponto já conseguimos criar e logar com o nosso usuário. Agora nos falta um mapa e a lista dos imóveis e é exatamente isso que faremos.

Primeiro passo

Será utilizado neste post o mapa já conhecido pela comunidade, o Mapbox. Primeiro é necessário criar uma conta no site da Mapbox. Uma vez criada a conta, basta copiar o access token, na área “Get your access token”:

Área do site Mapbox para pegar o access token

App

Essa será a página central do aplicativo, e é em cima dela que será construído o App. Para facilitar o trabalho com a utilização do Mapbox no ReactJS usaremos uma lib mantida pelo Uber, o react-map-gl e o react-dimensions que depois explico sobre ele.

npm install react-map-gl react-dimensions

Agora você precisa configurar a página seguindo o mesmo padrão até aqui:

src/pages/
      |--- App/
              |--- index.js
              |--- styles.js

Comesse com o styles.js:

Neste componente é preciso usar o PropTypes para validar os valores de entrada do componente, isso é uma boa prática e te ajudará caso esqueça de passar alguma propriedade ou mesmo um valor errado. Os PropTypes ficarão no static propTypesClique aqui para saber mais sobre ele. No index.js:

Observe que as informações como longitude e latitude foram mantidas no estado do Componente, pois com o evento onViewportChange conseguimos mudar a posição do mapa na página. Outra coisa é que usamos o Dimensions para conseguir aumentar o tamanho do mapa para o tamanho inteiro da página, isso acontece pois é preciso definir um width e um height, exigência do react-map-gl, e sem ele não saberíamos o tamanho exato.

Só para reforçar, o Dimensions pega a dimensão do componente pai, então temos o Container que é o elemento pai do Dimensions e que ocupa toda a tela, então esse width e height é passado para o react-map-gl.

Adicione no routes.js:

Página App do clone do AirBnB com o Mapbox funcionando

Funcionalidades

Agora é preciso listar os móveis sobre o mapa, para quando clicar saber as informações sobre esse eles. Para isso você deve buscar na API a lista de propriedades e criar o componente que vai conter as informações da delas.

Componente Properties

Primeiro você deve criar um diretório que conterá os componentes relacionados ao App, e já adicionar o componente Properties:

App/
 |--- components/
     |--- Properties/
            |--- index.js
            |--- styles.js

No index.js, terá apenas uma lista com o valor dos imóveis. Para trabalhar com o valor do Real será utilizado o objeto Intl.NumberFormat, que serve para transformar números em moedas. É bom reparar o Marker também, já que ele será importante para fixar o preço no mapa quando movimentarmos e permanecer na posição dele no mapa. Por fim, será utilizado o (lindo) StyledComponent para estilizar a div com o nome de Pin. Não se preocupe com o Link, ele servirá para nós mais tarde.

No index.js:

Nesse componente foi utilizado dois PropTypes bem comuns. O PropTypes.arrayOf define que aquela propriedade será um Array e o PropTypes.shape que é utilizado para definir pelo menos as keys mais importantes de um Object que devem estar na propriedade do componente.

No styles.js:

Listando os móveis

Agora no App/index.js você precisa consumir os dados da API do AdonisJS, que já foi criada, colocar as properties no estado do componente e exibi-la através do componente que acabou de ser criado. Bora fazer isso então?

No index.js importaremos o seguinte:

Sobre o debounce, talvez você esteja se perguntando: Mas que raios é isso? Calma, ele é uma função que retarda a execução de uma outra função passada em um tempo determinado. No nosso caso, toda vez que o mapa for movimentado queremos pegar de acordo com a longitude e latitude as novas propriedades, só tem um porém. Imagina fazer uma requisição toda vez que o estado do mapa for alterado? O que ocorre dezenas e as vezes centena de vezes por segundo. O servidor ou Browser acabariam entrando em parafuso. É nesse ponto que o debounce entra em cena, toda a vez que a função updatePropertiesLocalization (já já você verá ela) o debounce pega a última chamada dela, se em um 500 milissegundos não existir nenhuma outra chamada, ela busca na API as properties de acordo com a nova localização!!! Massa, né?

Dentro do componente App, adicione um construtor:

Ele será útil para reescrever a função do updatePropertiesLocalization, que agora contará com o debounce encapsulando ela.

Adicione também no state:

Ainda dentro do componente App:

No componenteDidMount ,que é chamado assim que o componente é montado, executa a loadProperties para resgatar as properties da API. No updatePropertiesLocalization também executa a função responsável por pegar os dados na API. Na função loadProperties a latitude e longitude que está no estado do componente são resgatadas e utilizadas como parâmetros da requisição, observe que não foi preciso passar o token, visto que isso já foi configurado lá na criação da api com o interceptor.

E para finalizar, ajuste o render:

No render as properties são pegas do estado do componente para preencher a lista do componente Properties. Foi utilizado o onViewStateChange para chamar a função responsável por resgatar as novas properties assim que o mapa altera a sua posição, lembre-se que respeitando o debounce.

Página App do clone do AirBnB com o Mapbox listando as properties

Dando tchau

Calma aí, que é o logout!!!

Pra finalizar esse Post, é preciso adicionar um botão para dar LogOut. Para isso, deve ser criado um novo componente, no mesmo diretório que ficou o Properties :

App/
 |--- components/
     |--- Button/
            |--- index.js
            |--- styles.js

No index.js :

Sobre o componente não tenho muito a dizer, mas sobre a estilização… Primeiro observe a lib polished, com ela temos diversas funcionalidades para serem utilizadas no CSS, aqui foi utilizada a darken que trabalha em cima de uma cor e de acordo com um range ele retorna a cor passada escurecida.

// Não se esqueça 
npm install polished

Outra coisa sensacional, é possível ter acesso as propriedades do componente dentro da estilização, utilizando ${({ color }) => color} , que nesse caso o color foi desestruturado, dessa maneira fica fácil pegar a cor recebida no Button e usar o darken quando fizer o hover e active.

Aproveitando o embalo da estilização, vá em no App/styles.js e adicione o código:

No ButtonContainer ficará os Button principais.

Agora no index.js da Page App, adicionar o seguinte:

Foi importado o Fragment que serve apenas para encapsular outros elementos, além disso o withRouter também foi importado para cuidar da navegação, o logout que será responsável por remover o token, o componente Button customizado e o ButtonContainer para deixar o Button no canto inferior da tela.

Ainda no index.js:

Para separar um pouco as coisas foi criada a função renderActions que conterá os Button que eventualmente estiverem na parte inferior. O render foi ajustado para receber os elementos “lado a lado” com o Fragment.

Foi criada a função handlerLogout que chama o logout e depois manda o usuário para a página inicial.

Por fim, agora o DimensionedMap possui também o withRouter, que como eu havia falado, serve para adicionar o history que trata da navegação para nós.
AirBnB with mapbox and logout

Por hoje é só!!!

Cara o App está ficando bruto, não??

Nesse post, vimos como adicionar o mapa com Mapbox, além de listar os imóveis nele. Também deslogamos o usuário da sessão que ele estava.

Código desse post está aqui.

Se você está gostando dessa série mais querida que a série do Brasileirão deixe o seu comentário e não se esqueça de compartilhar com aquele seu amigo dev.

Ah, e ainda tem mais então fica de olho no blog!!!

Abraços!!

AdonisJS + ReactJS + React Native
A seguir:

Utilizando o ModalRoute e fazendo upload de imagens

Utilizando o ModalRoute e fazendo upload de imagens