Aniversário
Alura 12 anos

20% OFF

Falta pouco!

00

DIAS

00

HORAS

00

MIN

00

SEG

Alura > Cursos de Mobile > Cursos de > Conteúdos de > Primeiras aulas do curso React Native: praticando customizações

React Native: praticando customizações

Gabarito comentado - Apresentação

Introdução ao Curso de Prática

Olá! Sejam muito bem-vindos a mais este curso de prática. Meu nome é Vinícius Neves, conhecido como o Deve Careca Barbudo, da Alura. Desta vez, estamos em uma abordagem diferente. No curso anterior, aprendemos a utilizar o Expo Halter. Ao finalizá-lo, ainda restavam algumas estilizações e lógicas que já tínhamos conhecimento para concluir. Fizemos um acordo diferente: no final daquele curso, sugeri que vocês praticassem, terminassem de desenvolver o aplicativo, e depois eu apresentaria uma solução comentada, mostrando minha forma de resolver o problema. Prometi que faria isso, e agora estamos aqui para revisar e encontrar a solução desse desafio.

Continuação do Projeto AppFocus

A partir do próximo vídeo, entraremos no simulador para finalizar o AppFocus, iniciado no curso anterior. Um detalhe importante: se vocês não participaram do curso anterior, recomendo fortemente que o façam para maximizar o aproveitamento desta técnica e prática de desenvolvimento em React Native. Caso ainda não tenham feito, podem continuar a partir daqui.

Preparação do Ambiente e Recomendações

No preparo do ambiente, é possível baixar o projeto e realizar o desafio proposto, mesmo sem ter concluído o curso anterior. No entanto, recomendamos que pause e faça o curso primeiro, para entender como desenvolvemos este aplicativo do zero, o que proporcionará maior familiaridade com ele. Caso deseje apenas praticar React Native, o projeto inicial está disponível e você pode executar o desafio proposto.

Ajustes no Menu de Navegação e Lista de Tarefas

Entre as atividades, ajustaremos nosso menu de navegação, que possui alguns itens que precisam ser modificados, e finalizaremos nossa lista de tarefas. Vamos criar um estado chamado Empty State (estado vazio), que exibirá uma mensagem amigável caso não haja itens na lista. Será possível adicionar itens à lista, como "estudar React", e manter esse comportamento com código reaproveitável.

Adicionando e Editando Itens na Lista

Para adicionar um item à lista, podemos começar com um exemplo simples, como adicionar a tarefa "Estudar React":

// Adicionando um item à lista
const tarefa = "Estudar React";

Esse código representa a adição de um item à lista de tarefas. Agora, vamos ver como podemos editar essa tarefa, por exemplo, alterando para "Estudar React Native", e manter as funcionalidades antigas.

// Editando o item da lista
const tarefaEditada = "Estudar React Native";

Boas Práticas e Recomendações Finais

Durante essa prática, aprenderemos boas práticas e recomendações sobre como lidar com componentes reaproveitáveis e muito mais. Reiteramos que, se ainda não fez o último curso, é aconselhável fazê-lo primeiro antes de iniciar esta prática. Caso já possua experiência com React Native e deseje apenas praticar, será muito bem-vindo. No preparo do ambiente, a próxima atividade contém a descrição detalhada do que precisa ser feito e onde estamos no processo.

Desejamos boa sorte e uma boa prática. Nos encontraremos na solução quando concluir.

Gabarito comentado - Preparando a navegação

Organização Inicial e Ajustes no Roteamento

Seguindo na evolução e finalização do nosso aplicativo, vamos começar organizando os componentes reutilizáveis e preparando o nosso roteamento. Estamos com o projeto aberto no VSCode, e ao lado direito temos um emulador, simulador de iOS. Ao clicar em "quero iniciar", ele carrega por padrão a página do Pomodoro. Se abrirmos o Drawer, aparece a opção "Edit Task" para editar a tarefa por ID. Um excelente primeiro passo é esconder esse menu.

Outro detalhe é que, ao entrar na lista de tarefas e solicitar a adição de uma nova tarefa, a ação do botão é voltar, e não abrir o Drawer novamente. Precisamos fazer esses dois ajustes: esconder o menu do Drawer e ajustar o ícone de ação.

Modificações no Código para Esconder o Menu

Vamos para o código. No arquivo Focus_App_layout.jsx, expandimos o Children, colapsamos a estrutura de pastas e descemos até a linha 32, onde estamos escondendo a rota edit-task-index. Vamos esconder o edit-task-id. Primeiro, pegamos todo o bloco do edit-task, pois faremos algo exatamente igual. Copiamos e colamos na linha de baixo, ajustando o name. Lembramos que o name deve ser único, então trocamos de ed para edit e, ao invés de index, usamos [id]. Com isso, ele já esconde no Drawer e remove o título, pois no nosso Figma não exibimos o título da tela.

<Drawer.Screen
  name='edit-task/[id]'
  options={{
    drawerItemStyle: { display: 'none' },
    title: '',
    headerLeft: () => {
      return <Ionicons
        name='arrow-back'
        size={24}
        color='#FFF'
        style={{ marginLeft: 16 }}
        onPress={() => router.navigate('/tasks')}
      />
    }
  }}
/>

Verificamos se funcionou: ao voltar para a lista de tarefas e abrir o Drawer, já não está lá, então metade do problema está resolvido. Ao clicar para editar, por exemplo, o React Native, o ícone de ação de voltar já aparece. Está funcionando, mas há algo que queremos destacar. Temos o header-left que passamos como uma propriedade, e o IonIcon de ArrowBack está repetido.

Criação de Componente Reutilizável

Podemos extrair esse componente repetido para um componente reutilizável. Vamos pensar em como fazer isso. Na estrutura de pastas, clicamos em "componente", criamos um novo arquivo chamado BackButtonDrawer e, dentro dele, criamos um index.jsx.

O que precisamos retornar é exatamente o que está aqui, sem alterações. Vamos copiar o IonIcon e é isso que devemos retornar. Então, vamos criar uma constante e já fazer o export:

export const BackButtonDrawer = () => {
  return (
    <Ionicons
      name='arrow-back'
      size={24}
      color='#FFF'
      style={{ marginLeft: 16 }}
      onPress={() => router.navigate('/tasks')}
    />
  )
}

Vamos pedir para o VS Code formatar o documento. O IonIcon não está importado, então vamos importá-lo. O router também não está importado, então vamos importá-lo também.

import { Ionicons } from '@expo/vector-icons'
import { router } from 'expo-router'

Ajuste para Tornar o Componente Mais Flexível

No entanto, não queremos deixar o caminho "/task" fixo, pois, se formos usar em outro lugar e precisar voltar para uma página diferente, isso estará travado. Queremos receber isso em uma prop. Podemos criar uma prop, que ainda não existe. Na linha 4, vamos recebê-la por parâmetro. Precisamos criar um nome, certo? Vamos chamar de backHref, que indica para qual caminho devemos voltar. Essa mesma prop que recebemos será usada no navigate.

export const BackButtonDrawer = ({ backHref }) => {
  return (
    <Ionicons
      name='arrow-back'
      size={24}
      color='#FFF'
      style={{ marginLeft: 16 }}
      onPress={() => router.navigate(backHref)}
    />
  )
}

Implementação do Componente Reutilizável

Agora, em vez de repetir aquele código, podemos reaproveitar o BackButtonDrawer. No nosso headerLeft, em vez de fazer um return do IonIcon, faremos um return do BackButtonDrawer. Precisamos importá-lo e passar a prop backHref. Queremos fazer um retorno para "/tasks". Faremos o mesmo no nosso edit. O headerLeft se tornará esse BackButtonDrawer com um backHref do jeito que criamos.

import { BackButtonDrawer } from '../../../components/BackButtonDrawer'

<Drawer.Screen
  name='add-task/index'
  options={{
    drawerItemStyle: { display: 'none' },
    title: '',
    headerLeft: () => {
      return <BackButtonDrawer backHref='/tasks' />
    }
  }}
/>

<Drawer.Screen
  name='edit-task/[id]'
  options={{
    drawerItemStyle: { display: 'none' },
    title: '',
    headerLeft: () => {
      return <BackButtonDrawer backHref='/tasks' />
    }
  }}
/>

Verificação e Conclusão

Na teoria, tudo está funcionando. Vamos verificar? No terminal, vamos fazer um reload. Recarregou. Vamos iniciar o Drawer. Lista de tarefas. Clicamos em adicionar nova tarefa. Ao clicar em voltar, o comportamento foi mantido. Estudando React Native. Editando. Ao clicar em voltar, o comportamento foi mantido. Agora, nosso drawer está finalizado e não precisaremos mais mexer nele. Extraímos esse comportamento para um componente, e agora está bem organizado. Já temos um BackButtonDrawer reaproveitado. Se surgirem mais cenários onde ele precisa ser usado, podemos reaproveitá-lo passando a prop.

Vamos continuar refatorando um pouco mais de código para tornar os componentes ainda mais reaproveitáveis. Nos vemos na próxima!

Gabarito comentado - Deixando o formulário reaproveitável

Refatoração do Projeto e Criação do Componente FormTask

Vamos prosseguir com a refatoração do nosso projeto. Já criamos o BackButtonDrawer reutilizável. Agora, precisamos refatorar o formulário de adicionar tarefas para torná-lo também reutilizável.

No simulador, vamos focar no arquivo app.addTask.index.jsx no VS Code. Todo o comportamento e o JSX desse arquivo serão reutilizáveis. O que vamos modificar é o trecho de código da função SubmitTask, definida na linha 13. Vamos desacoplar o resultado do SubmitTask do JSX em si.

Para resolver isso, começaremos criando um novo componente dentro da pasta de componentes, que chamaremos de FormTask, e dentro dele, o arquivo index.jsx. Vamos transferir todo o conteúdo da tela de adicionar tarefas para esse novo componente, sem alterações iniciais. No entanto, precisamos desacoplar a funcionalidade de adicionar a tarefa e a navegação.

Ajustes no Componente FormTask

Primeiramente, ajustaremos o nome do componente de AddTask para FormTask. O que está sendo importado do contexto na linha 11 será removido. O SubmitTask pode permanecer como está por enquanto, mas o AddTask da linha 15 e o Router.navigate não existem mais. Com isso, podemos remover algumas importações desnecessárias. No VS Code, clicamos no final da linha e utilizamos a ferramenta de remoção de importações não utilizadas.

Vamos começar importando os componentes necessários para o FormTask:

import { KeyboardAvoidingView, Text, View, TextInput, Pressable, StyleSheet, Platform, TouchableWithoutFeedback, Keyboard } from "react-native";
import IconSave from "../../../components/Icons/IconSave";
import { useState } from "react";

Agora, vamos definir o componente FormTask:

export default function FormTask({ onFormSubmit }) {
  const [description, setDescription] = useState("");

  const submitTask = () => {
    if (!description) {
      return;
    }

    onFormSubmit(description);
    setDescription("");
  };

  return (
    <KeyboardAvoidingView
      style={styles.container}
      behavior={Platform.OS === "ios" ? "padding" : "height"}
    >
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.inner}>
          <Text style={styles.text}>
            Adicionar uma tarefa:
          </Text>
          <Text style={styles.label}>
            Em que você está trabalhando?
          </Text>
          <TextInput
            style={styles.input}
            numberOfLines={10}
            multiline={true}
            value={description}
            onChangeText={setDescription}
          />
          <View style={styles.actions}>
            <Pressable style={styles.button} onPress={submitTask}>
              <IconSave />
              <Text>
                Salvar
              </Text>
            </Pressable>
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
}

Esse componente FormTask agora é responsável por lidar com a entrada do usuário e chamar a função onFormSubmit passada como prop.

Integração do FormTask com AddTask

Em seguida, vamos pegar o nosso FormTask e transferi-lo para o nosso EditTask. Todo aquele JSX será removido, ficando vazio, e os estilos também serão eliminados. O que faremos é chamar o nosso componente FormTask. Esse componente recebe um onSubmit, e podemos reaproveitar o que já temos, que é o nosso SubmitTask. No entanto, o useState da linha 10 não é mais necessário, então o removemos. Agora, passaremos a receber a Description via parâmetro.

No arquivo app/add-task/index.jsx, vamos importar o FormTask e definir a função submitTask:

import { router } from "expo-router";
import FormTask from "../../components/FormTask";
import useTaskContext from "../../components/context/useTaskContext";

export default function AddTask() {
  const { addTask } = useTaskContext();

  const submitTask = (description) => {
    addTask(description);
    router.navigate("/tasks");
  };

  return <FormTask onFormSubmit={submitTask} />;
}

Agora, temos um componente muito enxuto, com um formulário reaproveitável. A função dessa tela é apenas cuidar da regra de negócio e repassar para o JSX. Desacoplamos o comportamento do componente.

Teste e Próximos Passos

Na teoria, tudo está muito bem. Será que continua funcionando? Podemos tentar adicionar uma tarefa. Primeiro, faremos um reload do aplicativo para garantir que as alterações foram aplicadas. No terminal, pressionamos R para reiniciar. Voltamos ao simulador, abrimos o drawer, acessamos a lista de tarefas e adicionamos uma nova tarefa. Digitamos "estudar boas práticas de react.js" e clicamos em salvar. Maravilha, a tarefa foi adicionada corretamente, mantendo o mesmo comportamento.

Agora, podemos finalmente cuidar do nosso formulário de edição. Por que só agora? Porque estávamos preparando o terreno, separando em componentes pequenas porções reaproveitáveis. Agora, podemos focar no que precisamos fazer, que é levar esse formulário para lá. Quando alguém submeter, em vez de adicionar, queremos fazer uma atualização. Vamos fazer isso no próximo vídeo. Até lá!

Sobre o curso React Native: praticando customizações

O curso React Native: praticando customizações possui 37 minutos de vídeos, em um total de 14 atividades. Gostou? Conheça nossos outros cursos de em Mobile, ou leia nossos artigos de Mobile.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Escolha a duração
do seu plano

Conheça os Planos para Empresas