Atividade 22: Lista de Tarefas (Avançada)
A evolução! Vamos deletar itens e transformar Strings vazias em Objetos JSON de verdade para riscar os checks!
🎯 O que vamos construir
-
✓
Mudar a Array do State para Objetos Complexos:
{ id: 1, text: 'Ler', feito: false } -
✓
Usar a Função do Mal
.filter()para excluir arquivos na Array -
✓
Usar a Função Mapeadora
.map()para Iniciar os checkboxes (Dar Check).
🗑️ Removendo da Matriz com Filter
A regra de ouro do React Mobile dita que nós não podemos meter a tesoura na Array Ativa do Estado original. A nossa táctica para "Deletar" um item é usar a Peneira do Javascript: a Função `.filter()`.
A Tática do Filter
O Filter Peneira e Cospe FORA uma Cópia Limpa do Array, contendo só O QUE PASSOU NO TESTE DO IF. Então nossa peneira deve dizer: "Passarão pela peneira para a lista 2.0 apenas os itens Cujo ID SEJA DIFERENTE do ID Escohido para Matar". Literalmente filtrando ele pra fora!
function apagarTarefa(idAlvo) {
// A Peneira: Filtra todos e SÓ DEVOLVE os que Não Sáo o ID Apagado
const arraySemONome = tarefas.filter( item => item.id !== idAlvo );
// Substitui Totalmente a Coleção de Trefas pela coleção Filtrada da peneira
setTarefas(arraySemONome);
}
💻 App ToDo Pro + Checks
Abra seu Expo Snack. Veremos uma UI elegante com botãozinho Lixo e checkbox de clique de Texto alterando cores da String!
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, FlatList, StyleSheet } from 'react-native';
export default function App() {
const [texto, setTexto] = useState('');
// Array agora é Complexo! Armazena Blocos de {} com 'feito' (Boolean)
const [tarefas, setTarefas] = useState([
{ id: Date.now().toString(), text: 'Passear com cachorro', feito: false }
]);
function adicionar() {
if (texto.trim() === '') return;
// Novo objeto Tarefa com tempo unico C++
const novaL = { id: Date.now().toString(), text: texto, feito: false };
setTarefas([...tarefas, novaL]);
setTexto('');
}
// Deletar com Peneira Filter (Joga fora o ID clicado)
function remover(idRemover) {
const listasLimpas = tarefas.filter(t => t.id !== idRemover);
setTarefas(listasLimpas);
}
// Marcar como Lido/Feito com Scanner MAP Inerter (Clona todos, altera 1)
function alternarFeito(idChecar) {
const mapaInvertido = tarefas.map( t => {
if(t.id === idChecar) {
return { ...t, feito: !t.feito }; // Inverte o checkzinho dele
}
return t; // Se não for ele, devolve normal
});
setTarefas(mapaInvertido);
}
return (
<View style={styles.container}>
<Text style={styles.title}>Tarefas da Semana</Text>
<View style={styles.rowForm}>
<TextInput style={styles.input} placeholder="Nova tarefa..." value={texto} onChangeText={setTexto} />
<TouchableOpacity style={styles.btnAdd} onPress={adicionar}>
<Text style={styles.btnTextPlus}>+</Text>
</TouchableOpacity>
</View>
<FlatList
data={tarefas}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={styles.card}>
{/* Lado Esquerdo - Botão que checa a Tarefa */}
<TouchableOpacity onPress={() => alternarFeito(item.id)} style={{flex:1}}>
<Text style={[styles.tarefaTxt, item.feito && styles.tarefaRiscada]}>
{item.feito ? '✅ ' : '⏳ '} {item.text}
</Text>
</TouchableOpacity>
{/* Lado Direito - Botão de Deletar Lixinho */}
<TouchableOpacity onPress={() => remover(item.id)} style={styles.btnDel}>
<Text style={styles.btnDelTxt}>🗑️</Text>
</TouchableOpacity>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#fdf4ff', paddingTop: 60, paddingHorizontal: 20 },
title: { fontSize: 28, fontWeight: 'bold', color: '#86198f', mb: 20, textAlign:'center', marginBottom:20 },
rowForm: { flexDirection: 'row', gap: 10, marginBottom: 20 },
input: { flex: 1, backgroundColor: 'white', padding: 15, borderRadius: 10, borderWidth: 1, borderColor: '#f0abfc' },
btnAdd: { backgroundColor: '#d946ef', width: 55, borderRadius: 10, alignItems: 'center', justifyContent: 'center'},
btnTextPlus: { color: 'white', fontSize: 24, fontWeight: 'bold'},
card: { backgroundColor: 'white', padding: 15, borderRadius: 10, marginBottom: 10, flexDirection: 'row', alignItems:'center', justifyContent: 'space-between', elevation:2 },
tarefaTxt: { fontSize: 16, color: '#4a044e' },
tarefaRiscada: { textDecorationLine: 'line-through', color: '#cbd5e1' },
btnDel: { backgroundColor: '#fee2e2', padding: 10, borderRadius: 8 },
btnDelTxt: { fontSize: 16 }
});