Early today I finished a To-Do list tutorial on YouTube for React Native and I decided to try add some features to it and so far it has been going well, I decided to export my app into an APK to have some fun seeing it working and I've realised that when the app closes I lose all of my saved To-Do items! Would there be anyway of doing that locally on the users Android device?
import React, { useState } from "react";
import {
KeyboardAvoidingView,
Platform,
StyleSheet,
Text,
TextInput,
Keyboard,
TouchableOpacity,
View,
} from "react-native";
import Modal from "react-native-modal";
import Task from "./components/Task";
import { faTrophy } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome";
export default function App() {
const [task, setTask] = useState();
const [taskItems, setTaskItems] = useState([]);
const [modalVisable, setModalVisable] = useState(false);
const [itemToDelete, setItemToDelete] = useState();
const handleAddTask = () => {
Keyboard.dismiss();
setTaskItems([...taskItems, task]);
setTask(null);
};
const completeTask = (index) => {
let itemsCopy = [...taskItems];
itemsCopy.splice(index, 1);
setTaskItems(itemsCopy);
closeModal();
};
const closeModal = () => {
setModalVisable(false);
};
const handleRemoveTask = (index) => {
setModalVisable(true);
};
return (
<View style={styles.container}>
<View style={styles.tasksWrapper}>
<Text style={styles.sectionTitle}>Your Tasks</Text>
<View style={styles.items}>
{taskItems.map((item, index) => {
return (
<TouchableOpacity
key={index}
onPress={() => {
handleRemoveTask(index);
setItemToDelete(index);
}}
>
<Task text={item} />
</TouchableOpacity>
);
})}
</View>
</View>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.writeTaskWrapper}
>
<TextInput
style={styles.input}
placeholder={"Add a task!"}
value={task}
onChangeText={(text) => setTask(text)}
/>
<TouchableOpacity onPress={() => handleAddTask()}>
<View style={styles.addWrapped}>
<Text style={styles.addText}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
<View style={styles.modalWrapper}>
<Modal
style={styles.modal}
isVisible={modalVisable}
onBackdropPress={closeModal}
>
<Text style={styles.modalText}>Have you completed this task?</Text>
<FontAwesomeIcon
icon={faTrophy}
style={styles.trophyIcon}
size={96}
/>
<View style={styles.horizontalRule}>
<Text style={styles.modalDescription}>
If you confirm this task is complete it will be deleted and
removed from the app permanently
</Text>
</View>
<View style={styles.buttonArea}>
<TouchableOpacity
style={styles.closeButton}
onPress={() => closeModal()}
>
<Text style={styles.buttonText}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.completeButton}
onPress={() => completeTask(itemToDelete)}
>
<Text style={styles.buttonText}>Complete Task</Text>
</TouchableOpacity>
</View>
</Modal>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#E8EAED",
},
tasksWrapper: {
paddingTop: 80,
paddingHorizontal: 20,
},
sectionTitle: {
fontSize: 24,
fontWeight: "bold",
},
items: {
marginTop: 30,
},
writeTaskWrapper: {
position: "absolute",
bottom: 50,
width: "100%",
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
},
input: {
paddingVertical: 15,
paddingHorizontal: 15,
backgroundColor: "#FFF",
borderRadius: 60,
borderColor: "#C0C0C0",
borderWidth: 1,
textAlign: "center",
width: "70%",
},
addWrapped: {
width: 60,
height: 60,
backgroundColor: "#FFF",
borderRadius: 60,
borderColor: "#C0C0C0",
borderWidth: 1,
justifyContent: "center",
alignItems: "center",
},
addText: {},
modalWrapper: {},
modal: {
justifyContent: "flex-start",
alignSelf: "center",
top: 100,
borderRadius: 5,
backgroundColor: "#FFF",
maxWidth: 350,
maxHeight: 300,
padding: 25,
},
modalText: {
fontSize: 20,
fontWeight: "normal",
textAlign: "center",
},
buttonText: {
fontWeight: "bold",
textAlign: "center",
},
buttonArea: {
position: "relative",
flexWrap: 'nowrap',
alignContent: "center",
justifyContent: "space-between",
flexDirection: "row",
paddingTop: 5,
minWidth: 100,
maxWidth: 350,
top: 5,
},
completeButton: {
justifyContent: "center",
alignSelf: "center",
width: 140,
height: 36,
borderRadius: 10,
backgroundColor: "#B096F9",
},
closeButton: {
justifyContent: "center",
alignSelf: "center",
width: 140,
height: 36,
borderRadius: 10,
backgroundColor: "#FF8989",
},
trophyIcon: {
padding: 75,
color: "#F8C511",
alignSelf: "center",
},
modalDescription: {
textAlign: "center",
fontSize: 14,
borderColor: "#AFAFAF",
borderTopWidth: 1,
borderBottomWidth: 1,
},
});