Baixe o app para aproveitar ainda mais
Prévia do material em texto
PONTIFÍCIA UNIVERSIDADE CATÓLICA DE MINAS GERAIS Curso : Tecnologia em Análise e Desenvolvimento de Sistemas Disciplina: : Desenvolvimento Web Full Stack Professora : Sinaide Bezerra Roteiro para prática em laboratório Intruções: Atividade individual Objetivo: Gerar de um formulário com lista de material contato com o uso de React Native. Ferramenta de desenvolvimento: Snack - React Native in the browser – Expo - https://snack.expo.dev Roteiro: A partir do código disponível no arquivo listamaterial_v1.zip efetue as seguintes alterações: Estados do formulário Vamos programar os estados dos campos, para que seus valores sejam armazenados em memória quando o usuário digitar neles. Importe a a função useState do React no AppForm.js. import React, {useState} from 'react'; Crie os objetos de estado e as funções de manipulação do estado interno à function AppForm, antes do return.. export default function AppForm({ navigation }) { const [descricao, setDescricao] = useState(''); const [quantidade, setQuantidade] = useState(''); function handleDescriptionChange(descricao){ setDescricao(descricao); } function handleQuantityChange(quantidade){ setQuantidade(quantidade); } function handleButtonPress(){ console.log({id: new Date().getTime(), descricao, quantidade}); navigation.navigate("AppList"); } https://snack.expo.dev/ Discuta com outros integrantes o que significa cada linha do código. Responda: O que acontece com está declaração e por quê? {id: new Date().getTime(), ...} O que vai acontecer com o comando: navigation.navigate("AppList"); Referencie as funções de manipulação de estado nas propriedades onChangeText dos inputs e onPress do botão. <TextInput style={styles.input} onChangeText={handleDescriptionChange} placeholder="O que está faltando em casa?" clearButtonMode="always" /> <TextInput style={styles.input} onChangeText={handleQuantityChange} placeholder="Digite a quantidade" keyboardType={'numeric'} clearButtonMode="always" /> <TouchableOpacity style={styles.button} onPress={handleButtonPress}> <Text style={styles.buttonText}>Salvar</Text> </TouchableOpacity> Atualize e teste a aplicação. Salvando no banco de dados local Os dados capturados pelos estados irão ser salvos no banco de dados local do dispositivo. Altere os imports do AppForm.js. import React, {useState} from 'react'; import { StatusBar } from 'expo-status-bar'; import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; Altere a função handleButtonPress para salvar os dados obtidos no nosso banco de dados async function handleButtonPress(){ const listItem = {id: new Date().getTime(), descricao, quantidade: parseInt(quantidade)}; let savedItems = []; const response = await AsyncStorage.getItem('items'); if(response) savedItems = JSON.parse(response); savedItems.push(listItem); await AsyncStorage.setItem('items', JSON.stringify(savedItems)); navigation.navigate("AppList", listItem); } Discuta com colegas o que significa cada linha do código. O que faz o comando await? Criando a listagem Crie o compontente AppItem.js para receber a listagem armazenada no banco de dados da seguinte forma: import React from 'react'; import {StyleSheet, Text, View, TouchableOpacity} from 'react-native'; export default function AppItem(props){ return ( <View style={styles.container}> <Text style={styles.textItem}>{props.item}</Text> <View style={styles.buttonsContainer}> <TouchableOpacity style={styles.deleteButton} > <Text style={styles.buttonText}>X</Text> </TouchableOpacity> <TouchableOpacity style={styles.editButton} > <Text style={styles.buttonText}>Editar</Text> </TouchableOpacity> </View> </View> ); } A função recebe um objeto props que conterá o texto do item a ser adicionado na listagem. Associe os estilos a seguir ao AppItem.js. const styles = StyleSheet.create({ container: { backgroundColor: '#fff', marginTop: 20, width: '100%' }, buttonsContainer: { flexDirection: 'row-reverse', alignItems: 'flex-end', borderBottomWidth: 1, borderBottomColor: '#CCC', paddingBottom: 10, marginTop: 10, }, editButton: { marginLeft: 10, height: 40, backgroundColor: 'blue', borderRadius: 10, padding: 10, fontSize: 12, elevation: 10, shadowOpacity: 10, shadowColor: '#ccc', alignItems: 'center' }, deleteButton: { marginLeft: 10, height: 40, width: 40, backgroundColor: 'red', borderRadius: 10, padding: 10, fontSize: 12, elevation: 10, shadowOpacity: 10, shadowColor: '#ccc', alignItems: 'center' }, buttonText: { color: '#fff', fontWeight: 'bold', }, textItem: { fontSize: 20, } }); Construa a lista no módulo AppList.js. Altere os imports para: import { StatusBar } from 'expo-status-bar'; import React, {useState} from 'react'; import { StyleSheet, View, Text, ScrollView } from 'react-native'; import AppItem from './AppItem'; Teste a lista com valores estáticos. Adicione ao componente: const [items, setItems] = useState([ {id: 1, quantidade: 5, descricao: "canetas" }, {id: 2, quantidade: 1, descricao: "caderno" }, {id: 3, quantidade: 0.5, descricao: "metro de fita" }, {id: 4, quantidade: 1, descricao: "pincel" }, ]); Adicione uma ScrollView (área com rolagem): 1 2 3 4 5 6 7 8 9 10 11 12 13 return ( <View style={styles.container}> <StatusBar style="light" /> <Text style={styles.title}>Lista de Compras</Text> <ScrollView style={styles.scrollContainer} contentContainerStyle={styles.itemsContainer}> { items.map(item => { return <AppItem key={item.id} id={item.id} item={item.quantidade + ' de ' + item.descricao} /> }) } </ScrollView> </View> ); A que se refere a contentContainerStyle? O que faz o items.map? Adicione os estilos a seguir: const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#D93600', alignItems: 'center', justifyContent: 'center' }, title: { color: '#fff', fontSize: 20, fontWeight: 'bold', marginTop: 50, marginBottom: 20 }, scrollContainer: { flex: 1, width: '90%' }, itemsContainer: { flex: 1, marginTop: 10, padding: 20, borderTopLeftRadius: 10, borderTopRightRadius: 10, alignItems: 'stretch', backgroundColor: '#fff' }, }); Resultado esperado: . Refatorando o acesso a dados Crie um arquivo Database.js e adicione a lógica de acesso aos dados. Adicione o import: import AsyncStorage from '@react-native-async-storage/async-storage'; Adicione a função: async function saveItem(listItem){ listItem.id = new Date().getTime(); let savedItems = []; const response = await AsyncStorage.getItem('items'); if(response) savedItems = JSON.parse(response); savedItems.push(listItem); return AsyncStorage.setItem('items', JSON.stringify(savedItems)); } module.exports = { saveItem } No arquivo AppForm.js, import o módulo Database e altere a função handleButtonPress . import Database from './Database'; async function handleButtonPress(){ const listItem = {descricao, quantidade: parseInt(quantidade)}; Database.saveItem(listItem) .then(response => navigation.navigate("AppList", listItem)); } Retornando os itens do banco de dados No módulo Database.js adicionar a function. function getItems(){ return AsyncStorage.getItem('items') .then(response => { if(response) return Promise.resolve(JSON.parse(response));else return Promise.resolve([]); }) } Basicamente ela pega todos os itens do AsyncStorage e retorna em forma de array através de uma promise. https://www.luiztools.com.br/post/programacao-assincrona-em-nodejs-callbacks-e-promises/ No final do arquivo adicione o module.exports. module.exports = { saveItem, getItems } Pesquise o que faz um promisse. No arquivo AppList adicione o useEffect e o Database. Veja os imports a seguir: import { StatusBar } from 'expo-status-bar'; import React, {useState, useEffect} from 'react'; import { StyleSheet, View, Text, ScrollView } from 'react-native'; import AppItem from './AppItem'; import Database from './Database'; Altere a assinatura da função para que decomponha em dois objetos, um route e um navigation. export default function AppList({ route, navigation }) O navigation é utilizado para trocar de tela. O route, são os parâmetrosS de navegação que trouxeram até esta tela. Altere o useState que estava com valores pré-defindos para que sejam obtidos do banco de dados. const [items, setItems] = useState([]); useEffect(() => { Database.getItems().then(items => setItems(items)); }, [route]); O useEffect dispara todas as vezes que a variável route é alterada. Teste a aplicação. Estados do formulário Salvando no banco de dados local Refatorando o acesso a dados Crie um arquivo Database.js e adicione a lógica de acesso aos dados. Adicione a função: Retornando os itens do banco de dados
Compartilhar