Create a Task Manager App using React-Native
In this article, we'll walk you through the process of building a basic Task Manager app using React Native. The application enables users to effortlessly create, edit, complete/incomplete, and delete tasks, providing an uncomplicated yet impactful introduction to React Native's mobile app development capabilities.

To give you a better idea of what we’re going to create, let’s watch a demo video.
Demo Video
Prerequisites
- Introduction to React Native
- JavaScript
- React Native State
- React Native Props
- Expo CLI
- Node.js and npm (Node Package Manager)
Step-by-Step Implementation
Step 1: Create a React Native Project
Now, create a project with the following command.
npx create-expo-app app-name --template
Note: Replace the app-name with your app name for example : react-native-demo-app
Next, you might be asked to choose a template. Select one based on your preference as shown in the image below. I am selecting the blank template because it will generate a minimal app, as clean as an empty canvas in JavaScript.

It completes the project creation and displays a message: "Your Project is ready!" as shown in the image below.

Now go into your project folder, i.e., react-native-demo
cd app-name
Project Structure:

Step 2: Run Application
Start the server by using the following command.
npx expo start
Then, the application will display a QR code.
- For the Android users,
- For the Android Emulator, press "a" as mentioned in the image below.
- For the Physical Device, download the "Expo Go" app from the Play Store. Open the app, and you will see a button labeled "Scan QR Code." Click that button and scan the QR code; it will automatically build the Android app on your device.
- For iOS users, simply scan the QR code using the Camera app.
- If you're using a web browser, it will provide a local host link that you can use as mentioned in the image below.

Step 3: File Structure
Follow the file structure below to ensure better code organization.

Step 4: Start Coding
Approach
This code snippet in React Native allows you to build a simple task manager app effortlessly. It effectively manages the state using useState, enabling you to handle task data, editing functionality, and modal visibility smoothly. The app's interface presents a scrollable list of tasks, each featuring a title. By utilizing modals with title and content inputs, users can easily add, edit, complete/incomplete, and delete tasks.
Example: This example creates a Task Manager App using react-native
// App.js
// Import necessary modules and components
import { useState } from "react";
import {
View,
Text,
TouchableOpacity,
} from "react-native";
// Import TaskList component
import TaskList from "./components/TaskList";
// Import TaskModal component
import TaskModal from "./components/TaskModel";
import styles from "./styles"; // Import styles
// Define the main App component
const App = () => {
// Define state variables
// Array to store tasks
const [tasks, setTasks] = useState([]);
const [task, setTask] = useState({
title: "",
description: "",
status: "Pending",
deadline: "",
createdAt: "",
});
// Task object for creating/editing tasks
// Modal visibility
const [modalVisible, setModalVisible] = useState(false);
// Task being edited
const [editingTask, setEditingTask] = useState(null);
const [validationError, setValidationError] =
useState(false); // Validation flag
// Function to add a new task or update an existing task
const handleAddTask = () => {
if (
task.title.trim() !== "" &&
task.deadline !== ""
) {
const currentDate = new Date();
const formattedDate =
currentDate.toLocaleString();
if (editingTask) {
// If editing an existing task, update it
const updatedTasks = tasks.map((t) =>
t.id === editingTask.id
? { ...t, ...task }
: t
);
setTasks(updatedTasks);
setEditingTask(null);
} else {
// If adding a new task, create it
const newTask = {
id: Date.now(),
...task,
// Set the creation date and time as a string
createdAt: formattedDate,
};
setTasks([...tasks, newTask]);
}
// Clear the task input fields and reset state
setTask({
title: "",
description: "",
status: "Pending",
deadline: "",
createdAt: "",
});
// Close the modal
setModalVisible(false);
// Reset validation error
setValidationError(false);
} else {
// Show validation error if fields are not filled
setValidationError(true);
}
};
// Function to handle task editing
const handleEditTask = (task) => {
// Set the task being edited
setEditingTask(task);
// Pre-fill the input with task data
setTask(task);
// Open the modal for editing
setModalVisible(true);
};
// Function to delete a task
const handleDeleteTask = (taskId) => {
const updatedTasks = tasks.filter(
(t) => t.id !== taskId
);
setTasks(updatedTasks);
};
// Function to toggle task completion status
const handleToggleCompletion = (taskId) => {
const updatedTasks = tasks.map((t) =>
t.id === taskId
? {
...t,
status:
t.status === "Pending"
? "Completed"
: "Pending",
}
: t
);
setTasks(updatedTasks);
};
// Return the JSX for rendering the component
return (
<View style={styles.container}>
<Text style={styles.title}>Task Manager</Text>
{/* Render the TaskList component */}
<TaskList
tasks={tasks}
handleEditTask={handleEditTask}
handleToggleCompletion={
handleToggleCompletion
}
handleDeleteTask={handleDeleteTask}
/>
{/* Button to add or edit tasks */}
<TouchableOpacity
style={styles.addButton}
onPress={() => {
setEditingTask(null);
setTask({
title: "",
description: "",
status: "Pending",
deadline: "",
createdAt: "",
});
setModalVisible(true);
setValidationError(false);
}}>
<Text style={styles.addButtonText}>
{editingTask ? "Edit Task" : "Add Task"}
</Text>
</TouchableOpacity>
{/* Render the TaskModal component */}
<TaskModal
modalVisible={modalVisible}
task={task}
setTask={setTask}
handleAddTask={handleAddTask}
handleCancel={() => {
setEditingTask(null);
setTask({
title: "",
description: "",
status: "Pending",
deadline: "",
createdAt: "",
});
setModalVisible(false);
setValidationError(false);
}}
validationError={validationError}/>
</View>
);
};
// Export the App component as the default export
export default App;omponent as the default export
export default App;
// Import the ScrollView component from react-native for scrollable content
import { ScrollView } from "react-native";
// Import the TaskItem component to render individual tasks
import TaskItem from "./TaskItem";
// Import styles from the styles file
import styles from "../styles";
// Define the TaskList functional component with props for tasks and handlers
const TaskList = ({
tasks, // Array of task objects to display
handleEditTask, // Function to handle editing a task
handleToggleCompletion, // Function to toggle task completion status
handleDeleteTask, // Function to delete a task
}) => {
// Render the component
return (
// Scrollable container for the list of tasks, styled with taskList style
<ScrollView style={styles.taskList}>
{/* Iterate over each task in the tasks array */}
{tasks.map((t) => (
// Render a TaskItem component for each task
<TaskItem
key={t.id} // Unique key for each TaskItem using task's ID
task={t} // Pass the entire task object as a prop
handleEditTask={handleEditTask} // Pass edit handler function
handleToggleCompletion={handleToggleCompletion} // Pass toggle completion handler
handleDeleteTask={handleDeleteTask} // Pass delete handler function
/>
))}
</ScrollView>
);
};
// Export the TaskList component as the default export
export default TaskList;
// Import necessary components from react-native
import { View, Text, TouchableOpacity } from "react-native";
// Import styles from the styles file
import styles from "../styles";
// Define the TaskItem functional component with props
const TaskItem = ({
task, // The task object containing details
handleEditTask, // Function to handle editing a task
handleToggleCompletion, // Function to toggle task completion
handleDeleteTask, // Function to delete a task
}) => {
return (
// Container for the entire task item
<View style={styles.taskItem}>
{/* Container for task text details */}
<View style={styles.taskTextContainer}>
{/* Display the task title, with a different style if completed */}
<Text
style={[
styles.taskText,
task.status === "Completed" &&
styles.completedTaskText,
]}>
{task.title}
</Text>
{/* Display the task description */}
<Text style={styles.taskDescription}>
{task.description}
</Text>
{/* Display the task status */}
<Text style={styles.taskStatus}>
Status: {task.status}
</Text>
{/* Display the task deadline */}
<Text style={styles.taskDeadline}>
Deadline: {task.deadline}
</Text>
{/* Display the task creation date */}
<Text style={styles.taskCreatedAt}>
Created: {task.createdAt}
</Text>
</View>
{/* Container for action buttons */}
<View style={styles.buttonContainer}>
{/* Button to edit the task */}
<TouchableOpacity
onPress={() => handleEditTask(task)}
style={[styles.editButton]}>
<Text style={styles.buttonText}>
Edit
</Text>
</TouchableOpacity>
{/* Button to toggle completion status */}
<TouchableOpacity
onPress={() =>
handleToggleCompletion(task.id)
}
style={[
styles.completeButton,
task.status === "Completed" &&
styles.completedButton,
]}>
<Text style={styles.buttonText}>
{task.status === "Completed"
? "Pending"
: "Completed"}
</Text>
</TouchableOpacity>
{/* Button to delete the task */}
<TouchableOpacity
onPress={() =>
handleDeleteTask(task.id)
}
style={[styles.deleteButton]}>
<Text style={styles.buttonText}>
Delete
</Text>
</TouchableOpacity>
</View>
</View>
);
};
// Export the TaskItem component as default
export default TaskItem;
// Import necessary components from react-native
import {
View, // Container component for layout
Text, // Component for displaying text
TextInput, // Input field for text
Button, // Button component
Modal, // Modal dialog component
} from "react-native";
// Import styles from the styles file
import styles from "../styles";
// Import Calendar component for date picking
import { Calendar } from "react-native-calendars";
// Define the TaskModal functional component with props
const TaskModal = ({
modalVisible, // Boolean to control modal visibility
task, // Task object containing title, description, deadline, etc.
setTask, // Function to update the task state
handleAddTask, // Function to handle adding or updating a task
handleCancel, // Function to handle cancel action
validationError, // Boolean to indicate validation error
}) => {
return (
// Modal component to display the task form
<Modal
visible={modalVisible} // Show or hide modal based on modalVisible
animationType="slide" // Slide animation for modal appearance
transparent={false}> // Modal is not transparent
{/* Container for modal content */}
<View style={styles.modalContainer}>
{/* Input for task title */}
<TextInput
style={styles.input} // Style for input
placeholder="Title" // Placeholder text
value={task.title} // Value from task object
onChangeText={(text) => // Update task title on change
setTask({ ...task, title: text })
}
/>
{/* Input for task description */}
<TextInput
style={styles.input} // Style for input
placeholder="Description" // Placeholder text
value={task.description} // Value from task object
onChangeText={(text) => // Update task description on change
setTask({
...task,
description: text,
})
} />
{/* Label for deadline */}
<Text style={styles.inputLabel}>
Deadline:
</Text>
{/* Calendar component for selecting deadline */}
<Calendar
style={styles.datePicker} // Style for calendar
markedDates={ // Highlight selected date
task.deadline
? { [task.deadline]: { selected: true, selectedColor: '#007BFF' } }
: {}
}
onDayPress={(day) => // Update deadline on date selection
setTask({ ...task, deadline: day.dateString })
}
current={task.deadline} // Set current date in calendar
/>
{/* Show validation error if present */}
{validationError && (
<Text style={styles.errorText}>
Please fill in all fields correctly.
</Text>
)}
{/* Button to add or update task */}
<Button
title={task.id ? "Update" : "Add"} // Show "Update" if editing, else "Add"
onPress={handleAddTask} // Call handleAddTask on press
color="#007BFF" /> // Button color
{/* Button to cancel and close modal */}
<Button
title="Cancel" // Button label
onPress={handleCancel} // Call handleCancel on press
color="#FF3B30" /> // Button color
</View>
</Modal>
);
};
// Export the TaskModal component as default
export default TaskModal;
// Import StyleSheet from react-native for creating styles
import { StyleSheet } from "react-native";
// Create a StyleSheet object to hold all styles
const styles = StyleSheet.create({
// Main container style
container: {
flex: 1, // Take up the full screen
padding: 30, // Padding around the content
backgroundColor: "#f7f7f7", // Light gray background
},
// Title text style
title: {
fontSize: 28, // Large font size
fontWeight: "bold", // Bold text
marginBottom: 20, // Space below the title
color: "#333", // Dark text color
textAlign: "center", // Center the text
},
// Task list container style
taskList: {
flex: 1, // Take up available space
},
// Individual task item style
taskItem: {
flexDirection: "row", // Arrange children in a row
justifyContent: "space-between", // Space between children
alignItems: "center", // Center items vertically
backgroundColor: "#fff", // White background
marginBottom: 10, // Space below each task
padding: 15, // Padding inside the task item
borderRadius: 10, // Rounded corners
},
// Container for task text
taskTextContainer: {
flex: 1, // Take up available space
},
// Main task text style
taskText: {
fontSize: 18, // Medium font size
fontWeight: "bold", // Bold text
color: "#333", // Dark text color
},
// Style for completed task text
completedTaskText: {
textDecorationLine: "line-through", // Strike-through text
color: "gray", // Gray color for completed tasks
},
// Task description text style
taskDescription: {
fontSize: 16, // Slightly smaller font
color: "#666", // Medium gray color
},
// Task time text style
taskTime: {
fontSize: 14, // Small font size
color: "#666", // Medium gray color
},
// Task status text style
taskStatus: {
fontSize: 16, // Medium font size
color: "#666", // Medium gray color
},
// Container for buttons (edit, complete, delete)
buttonContainer: {
flexDirection: "column", // Arrange buttons vertically
marginVertical: 2, // Vertical margin between buttons
},
// Edit button style
editButton: {
backgroundColor: "#007BFF", // Blue background
borderRadius: 5, // Rounded corners
padding: 10, // Padding inside the button
marginRight: 10, // Space to the right of the button
width: 110, // Fixed width
},
// Generic button style
button: {
marginBottom: 10, // Space below the button
},
// Complete button style
completeButton: {
backgroundColor: "#4CAF50", // Green background
borderRadius: 5, // Rounded corners
padding: 10, // Padding inside the button
marginRight: 10, // Space to the right of the button
width: 110, // Fixed width
},
// Style for completed (disabled) button
completedButton: {
backgroundColor: "#808080", // Gray background
},
// Button text style
buttonText: {
color: "#fff", // White text
fontSize: 15, // Medium font size
},
// Delete button style
deleteButton: {
backgroundColor: "#FF9500", // Orange background
borderRadius: 5, // Rounded corners
padding: 10, // Padding inside the button
width: 110, // Fixed width
},
// Add button style (for adding new tasks)
addButton: {
alignItems: "center", // Center content horizontally
justifyContent: "center", // Center content vertically
backgroundColor: "#007BFF", // Blue background
paddingVertical: 15, // Vertical padding
borderRadius: 10, // Rounded corners
marginTop: 20, // Space above the button
},
// Add button text style
addButtonText: {
color: "#fff", // White text
fontSize: 18, // Large font size
fontWeight: "bold", // Bold text
},
// Modal container style
modalContainer: {
flex: 1, // Take up the full screen
padding: 20, // Padding around the content
backgroundColor: "#fff", // White background
},
// Input field style
input: {
borderWidth: 1, // Border width
borderColor: "#ccc", // Light gray border
padding: 10, // Padding inside the input
marginBottom: 20, // Space below the input
borderRadius: 5, // Rounded corners
fontSize: 16, // Medium font size
},
// Input label style
inputLabel: {
fontSize: 16, // Medium font size
fontWeight: "bold", // Bold text
},
// Error text style
errorText: {
color: "#FF3B30", // Red color for errors
fontSize: 16, // Medium font size
marginBottom: 10, // Space below the error text
},
// Task deadline text style
taskDeadline: {
color: "#FF3B12", // Orange-red color for deadlines
},
// Task created-at text style
taskCreatedAt: {
color: "#5497FF", // Blue color for creation time
},
});
// Export the styles object for use in other files
export default styles;