I am creating a todo app in which I render Tasks, I implemented the create and delete functions but don't know how to do the update part. I am doing everything locally with state and I think I just need the right logic for this but I can't seem to find the right way to do it. The idea is when I click on the task I want to be able to change the text of the task or have a button that says "Edit" that does the same thing. Also how would I implement the local storage to make persistent data that stays there after it is rendered? Any feedback helps :)
Home screen, where the tasks are rednered - HomeScreen.js:
import React, { useEffect, useState } from "react";
import {
View,
Text,
StyleSheet,
Button,
TextInput,
KeyboardAvoidingView,
TouchableOpacity,
Keyboard,
} from "react-native";
import Task from "../components/Task";
export function HomeScreen({ route, navigation }) {
function handleNavPress() {
navigation.navigate("UserInfo");
}
const [task, setTask] = useState("");
const [taskItems, setTaskItems] = useState([]);
const handleAddTask = () => {
Keyboard.dismiss();
setTaskItems([...taskItems, task]);
setTask(null);
};
const completeTask = (index) => {
let itemsCopy = [...taskItems];
itemsCopy.splice(index, 1);
setTaskItems(itemsCopy);
};
return (
<View style={styles.container}>
<View style={styles.tasksWrapper}>
<View style={styles.navButton}>
<Button onPress={handleNavPress} title="user info" />
</View>
</View>
<View style={styles.items}>
{taskItems.map((item, index) => {
return (
<View key={index}>
<Task text={item} />
<View style={styles.btnContainer}>
<TouchableOpacity
style={styles.delete}
title="Delete task"
onPress={() => completeTask()}
>
<Text>Delete Task</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.edit}
title="Edit task"
onPress={() => console.log("pressed")}
>
<Text>Edit Task</Text>
</TouchableOpacity>
</View>
</View>
);
})}
</View>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.writeTaskWrapper}
>
<TextInput
style={styles.input}
placeholder={"Write a task"}
value={task}
onChangeText={(text) => setTask(text)}
/>
<TouchableOpacity
onPress={
!task
? () => alert("Enter the title of the task first")
: () => handleAddTask()
}
>
<View style={styles.addWrapper}>
<Text style={styles.addText}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</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: 60,
width: "100%",
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
},
input: {
paddingVertical: 15,
paddingHorizontal: 15,
backgroundColor: "#FFF",
borderRadius: 60,
borderColor: "#C0C0C0",
borderWidth: 1,
width: 250,
},
addWrapper: {
width: 60,
height: 60,
backgroundColor: "#FFF",
borderRadius: 60,
justifyContent: "center",
alignItems: "center",
borderColor: "#C0C0C0",
borderWidth: 1,
},
addText: {},
delete: {
backgroundColor: "red",
padding: 10,
borderRadius: 10,
},
edit: {
backgroundColor: "lightblue",
padding: 10,
borderRadius: 10,
},
btnContainer: {
alignSelf: "stretch",
flexDirection: "row",
justifyContent: "space-around",
},
navButton: {
maxWidth: 160,
bottom: 55,
},
});
Reusable component - Task.js:
import React, { useState } from "react";
import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
import { TextInput } from "react-native-web";
const Task = (props) => {
const [editText, setEditText] = useState(false);
return (
<View style={styles.item}>
<View style={styles.itemLeft}>
<View style={styles.square}></View>
<Text>{props.text}</Text>
</View>
<View style={styles.circular}></View>
</View>
);
};
const styles = StyleSheet.create({
item: {
backgroundColor: "#FFF",
padding: 15,
borderRadius: 10,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginBottom: 20,
marginRight: 10,
marginLeft: 10,
},
itemLeft: {
flexDirection: "row",
alignItems: "center",
flexWrap: "wrap",
},
square: {
width: 24,
height: 24,
backgroundColor: "#55BCF6",
opacity: 0.4,
borderRadius: 5,
marginRight: 15,
},
itemText: {
maxWidth: "80%",
},
circular: {
width: 12,
height: 12,
borderColor: "#55BCF6",
borderWidth: 2,
borderRadius: 5,
},
});
export default Task;