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.
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.
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.
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.
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";
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.
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.
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.
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'
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)}
/>
)
}
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' />
}
}}
/>
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!
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.
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.
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.
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á!
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:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS (1 ANO) e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS (1 ANO) e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO (1 ANO) e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Brinde aniversário Alura
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Enquanto durarem os estoques