'how to make the app "keep" data in the screen on react native?
I am new to react native and I am building a shopping list app and use firebase as data storage. Currently I have 4 screens: Register, Login, Menu and shopping list where users can add a shopping list and the information will be sent to firebase. The problem is whenever the user finish creating the list and go back to menu or logout the system, the information disappears from the screen, how can prevent that?
import { KeyboardAvoidingView, StyleSheet, Text, View, Image, TouchableOpacity,TextInput, Alert} from 'react-native';
import React, {useState} from 'react';
import { useNavigation } from '@react-navigation/core'
import Carrot from '../assets/carrot.png'
import Grocery from '../assets/grocery.png'
import Tomatoes from '../assets/tomatoes.png'
import GroceryBag from '../assets/grocery_bag.jpg'
import { MaterialIcons } from '@expo/vector-icons';
import { AntDesign } from '@expo/vector-icons';
import { auth } from '../firebase'
import { ScrollView } from 'react-native';
import firebase from 'firebase';
const ShoppingListScreen = () => {
const [input, setInput] = useState('');
const [list, setList] = useState([]);
const navigation = useNavigation();
const addList = () => {
if(input)
{
console.log(input)
setList([...list,
{key:Math.random().toString(),
data:input
}]);
setInput('');
};
}
const removeList = (inputKey) => {
setList(list => list.filter(input => input.key != inputKey));
};
const handleSignOut = () => {
auth
.signOut()
.then(() => {
navigation.replace("Login")
console.log('User signed out!')
})
.catch(error => alert(error.message))
};
const sendDataToDB = () =>{
if(input)
{
firebase.database().ref('Shopping Lists/').push({
list
}).
then((data) => {
console.log('data', data)
}).catch(() => {
console.log('error', error)
})
};
}
const checkInput= () =>{
if( !input || input == " ")
{
alert("Empty Input")
}
};
return(
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
behavior={Platform.OS === "android" ? "padding" : "height"}
style={styles.container}
behavior="padding"
backgroundColor="white">
<View style={{flex: 1}}>
<Image style={styles.carrot}
source={Carrot}
resizeMode="contain">
</Image>
<Image style={styles.grocery}
source={Grocery}
resizeMode="contain">
</Image>
<Image style={styles.tomatoes}
source={Tomatoes}
resizeMode="contain">
</Image>
<Image style={styles.grocery_bag}
source={GroceryBag}
resizeMode="contain">
</Image>
</View>
<ScrollView>
{list.map((input) =>
<TouchableOpacity
key = {input.key}>
<View style = {styles.listViewer}
>
<Text style = {styles.viewerText}>{input.data}</Text>
<TouchableOpacity>
<View
style = {{
backgroundColor: '#fff',
borderRadius: 50,
padding: 5,
width: 30,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style = {styles.viewerText}>
<AntDesign
name='delete'
color={'#802b00'}
onPress={() => removeList(input.key)}>
</AntDesign>
</Text>
</View>
</TouchableOpacity>
</View>
</TouchableOpacity>)}
</ScrollView>
<View style={styles.footer}></View>
<View style={styles.signOutItem}>
<MaterialIcons
name='logout'
size={50}
color={'#fff'}
onPress={handleSignOut}
/>
<Text style={styles.LogOutLabels}>Logout</Text>
</View>
<View style={styles.homeItem}>
<AntDesign
name='home'
size={50}
color={'#fff'}
onPress={() => {navigation.navigate("Home")}}
/>
<Text style={styles.homeLabels}>Home</Text>
</View>
<View style={styles.plusItem}>
<MaterialIcons
name='add-circle'
size={50}
color={'#802b00'}
onPress={() => {checkInput();addList(); sendDataToDB()}}
/>
</View>
<TextInput style={{flex: 1}}
style={styles.listInput}
placeholder='Enter List Name'
value={input}
onChangeText={text => setInput(text)}
autoCapitalize='none'>
</TextInput>
</KeyboardAvoidingView>
);
};
export default ShoppingListScreen;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignContent: 'center',
alignItems: 'center',
},
viewerText:{
fontSize:15,
color:'#fff',
},
listViewer:{
justifyContent:"space-between",
backgroundColor:'#802b00',
width: 350,
padding: 10,
margin: 5,
borderRadius: 10,
flexDirection:"row",
},
carrot:{
position: 'absolute',
width: 100,
height: 200,
opacity: 0.2,
right: 100,
bottom: 70,
},
grocery:{
position: 'absolute',
width: 100,
height: 200,
opacity: 0.2,
left: 105,
bottom: -355,
},
tomatoes:{
position: 'absolute',
width: 100,
height: 200,
opacity: 0.2,
right: 90,
bottom: -350,
},
grocery_bag:{
position: 'absolute',
width: 100,
height: 200,
opacity: 0.2,
left: 90,
bottom: 80,
},
footer:{
backgroundColor:'#802b00',
width: '100%',
color :'white',
height:100,
position:'absolute',
bottom:0,
},
signOutItem:{
bottom:-132,
left: 45,
},
LogOutLabels:{
color:'#ffff',
right:5,
},
homeItem:{
bottom: -65,
right: 30,
color: 'black',
},
homeLabels:{
color:'#ffff',
right: -5,
},
plusItem:{
bottom: 100,
left: 150,
},
listInput:{
bottom: 147,
right: 50,
paddingHorizontal:15,
paddingVertical:10,
borderRadius:10,
marginTop:5,
alignItems: 'center',
backgroundColor:'#C0C0C0',
color:'#000000',
width: '60%',
},
});
Solution 1:[1]
There are 3 possible solutions:
Refetch data from firebase when users navigate back to the screen - Not best UX ever. React navigation provides
useFocusEffecthook for that.Save last user-added data in Async Storage and retrieve when the user revisit screen.
Use Redux with
redux-persistand persist portion of that app frequently needed data.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Shy Penguin |
