Se existe uma coisa que faz muitos Apps React Native pecarem é a falta de organização e padrão no Layout. Isso porque apps construídos com ele requerem um mínimo de estilização e métricas, que as vezes é complicado compreender.

Se te incomoda cuidar desses detalhes existe algumas bibliotecas focadas nisso, e sua atenção se volta apenas ao negócio da aplicação.

Hoje neste post mostraremos uma biblioteca muito simples e robusta, o NativeBase, que cuidará disso sem problemas. Com ele você terá uma gama de componentes construídos para se comportarem como nativos em Android e iOS.

Como funciona?

O NativeBase servirá apenas para cuidar do Layout da aplicação, nada mais é do que as estilizações em cima de componentes. Com ele teremos componentes como Header, Tabs,  List, Button, Card e entre outros prontos para usarmos, precisando apenas de organizarmos os mesmos.

Com isso o Layout será ajustado tanto para Android quanto iOS, cada um seguindo seu Design padrão:

Observe que o componente utilizado é o mesmo, ListItem, entretanto o Design permaneceu nativo de cada plataforma, essa é a grande sacada do NativeBase.

Instalação

Como na maioria das bibliotecas, não há segredos para sua instalação. Primeiro criaremos um projeto:

react-native init rocketapp

Umas vez com ele criado, instalaremos o NativeBase:

yarn add native-base
// ou npm install native-base

Por depender de outras bibliotecas, como o caso da fonte de ícones, e ela por sua vez altera a estrutura nativa, usaremos o link fazer isso:

react-native link native-base

Pronto!! Já temos tudo configurado para utilizamos essa biblioteca fantástica. Basta rodamos nossa aplicação.

react-native run-android
// ou react-native run-ios

Aplicação like a boss

E é lógico que vamos vamos fazer algo juntos, somos a Rocketseat!!!!

Dividirei os códigos por partes, assim ficará mais fácil entender!!

Por estar tudo num arquivo só, importaremos um caminhão de componentes, então no App.js:

import React, { Fragment } from 'react';
import { Container, Header, Left, Right, Body, Title, Button, Icon, View, Fab, List, ListItem, Thumbnail, Text, Badge, Content, Tab, Tabs, TabHeading, Card, CardItem } from 'native-base';
import { Image, StyleSheet } from 'react-native';

Alguns dados para utilizamos no nosso App:

const messages = [
  { id: 1, name: 'Diego Fernandes', avatar_url: 'https://avatars0.githubusercontent.com/u/2254731?s=460&v=4', last_message: 'Lorem ipsum', time: '18:20 PM' },
  { id: 2,name: 'Claudio Orlandi', avatar_url: 'https://secure.gravatar.com/avatar/4a75e363796021a2bc2b9f805bacc2da?s=500&d=mm&r=g', last_message: 'Lorem ipsum', time: '10:12 AM' },
];

const blogList = [
  { id: 1, title: 'Implementando Shimmer Effect no React Native', author: 'Claudio Orlandi', author_avatar: 'https://secure.gravatar.com/avatar/4a75e363796021a2bc2b9f805bacc2da?s=500&d=mm&r=g', cover_image_url: 'https://blog.rocketseat.com.br/wp-content/uploads/2018/06/capa_react-native-shimmer-868x488.png', likes: 1290, comments: 129, time: '21 de Junho' },
  { id: 2,title: 'Utilizando mapas no React Native com Mapbox', author: 'Higo Ribeiro', author_avatar: 'https://secure.gravatar.com/avatar/8834a7ccea235ca4cca9c970d95e27f3?s=500&d=mm&r=g', cover_image_url: 'https://blog.rocketseat.com.br/wp-content/uploads/2060/06/react-native-map-mapbox-868x488.png', likes: 1290, comments: 129, time: '20 de Junho' },
];

Agora vamos criar a base do nosso App, onde haverá um Header, TabBar e uma pequena estilização:

const Home = ({ blogList }) => null;
const Messages = ({ messages }) => null;
const Notification = () => null;

const logo_url = 'https://avatars0.githubusercontent.com/u/28929274?s=200&v=4';

const App = () => (
  <Container>
    <Header androidStatusBarColor="#573ea8" style={styles.header} hasTabs>
      <Left>
        <Thumbnail small source={{ uri: logo_url }} />
      </Left>
      <Body>
        <Title>Rocketseat</Title>
      </Body>
    </Header>
    <View style={styles.container}>
    <Tabs>
      <Tab heading={<TabHeading style={styles.tabHeading} ><Icon type="FontAwesome" name="home" /></TabHeading>}>
        <Home blogList={blogList}/>
      </Tab>
      <Tab heading={<TabHeading style={styles.tabHeading} ><Icon type="FontAwesome" name="bell-o" /></TabHeading>}>
        <Notification />
      </Tab>
      <Tab heading={<TabHeading style={styles.tabHeading} ><Icon type="FontAwesome" name="envelope-o" /></TabHeading>}>
        <Messages messages={messages}/>
      </Tab>
    </Tabs>
    </View>
  </Container>
);

export default App;

const styles = StyleSheet.create({
  tabHeading: {
    backgroundColor: "#7159C1",
  },
  header: { 
    backgroundColor: "#7159C1",
  },
  container: {
    flex: 1,
  }
});

Observe que com poucos códigos já temos a cara do App definida. No Header adicionamos a propriedade androidStatusBarColor para forçar a cor que queremos no StatusBar do Android. No iOS ele pega a cor do Header.

No código coloquei Home, Notification e Message como componentes null para fazermos em seguida. Teremos algo parecido com isso:

Tab Home

Agora definiremos o conteúdo da nossa Tab Home, que será a apresentação de dois post do blog em forma de uma lista de Cards. Substituiremos o null pelo código abaixo:

const Home = ({ blogList }) => (
   <Content>
    {blogList.map(blog => (
    <Card key={blog.id}>
      <CardItem>
        <Left>
          <Thumbnail source={{ uri: blog.author_avatar}} />
          <Body>
            <Text>{blog.title}</Text>
            <Text note>{blog.author}</Text>
          </Body>
        </Left>
      </CardItem>
      <CardItem cardBody>
        <Image source={{ uri: blog.cover_image_url}} style={{height: 200, width: null, flex: 1}}/>
      </CardItem>
      <CardItem>
        <Left>
          <Button transparent>
            <Icon active name="thumbs-up" />
            <Text>{blog.likes}</Text>
          </Button>
        </Left>
        <Body>
          <Button transparent>
            <Icon active name="chatbubbles" />
            <Text>{blog.comments}</Text>
          </Button>
        </Body>
        <Right>
          <Text note>{blog.time}</Text>
        </Right>
      </CardItem>
    </Card>))}
  </Content>
);

Precisamos notar a organização e o que cada componente representa com suas respectivas propriedades. Mais detalhes sobre Card.

Tab Messages

O conteúdo desse Tab será uma lista de mensagens de usuários e mais uma vez o NativeBase disponibiliza tudo pronto, precisamos apenas saber organizar os componentes.

Neste TabMessages colocaremos um FAB (Floating Action Button) para “adicionarmos” mais usuários na conversa. Dale código:

const Messages = ({ messages }) => (
  <Fragment>
    <List>
      {messages.map( message => (
        <ListItem avatar key={message.id}>
          <Left>
            <Thumbnail source={{ uri: message.avatar_url}} />
          </Left>
          <Body>
            <Text>{message.name}</Text>
            <Text note>{message.last_message}</Text>
          </Body>
          <Right>
            <Text note>{message.time}</Text>
          </Right>
        </ListItem>
      ))}
    </List>
    <Fab
      direction="up"
      position="bottomRight"
      style={{ backgroundColor: "#7159C1"}}
    >
      <Icon type="FontAwesome" name="plus" />
    </Fab>
  </Fragment>
);

É como se cada componente falasse por si só!! Mais sobre List.

Tab Notification

Poderíamos fazer esse componente juntos, mas que tal você mostrar o que aprendeu e fazê-lo? Esse é o meu desafio para você!! Não esquece de postar lá na comunidade hehe.

Não é adeus, é até logo!!!

Então, fala que não é simples?? E como é comum na comunidade existem outras alternativas, mas hoje ficaremos com essa biblioteca *—*.

Se há alguma dúvida sobre o React Native e algumas funcionalidades do ES6+, não deixa de se inscrever no nosso curso gratuito sobre React Native e ES6+.

Ah é!! Não esqueça de compartilhar com seus amigos Devs e podes deixar também um comentário maroto ali embaixo :P.

Código no github: https://github.com/Rocketseat/blog-native-base

See you later!!