Final Project: Building a Full-Featured React Application
In this final lesson, we will consolidate our learning by building a comprehensive React application that incorporates all the concepts covered throughout this course. By the end of this lesson, you will have a fully functional application that demonstrates your understanding of React principles, components, state management, routing, and more.
Learning Objectives
By the end of this lesson, you will be able to: - Design and implement a full-featured React application. - Utilize components, state, props, and hooks effectively. - Implement routing for navigation. - Integrate API calls into your application. - Style your application using CSS or styled-components.
Project Overview
For our final project, we will create a simple Task Management Application. This application will allow users to: - Add new tasks. - Mark tasks as completed. - Delete tasks. - View a list of tasks.
This project will demonstrate the use of various React concepts, such as components, state management, props, hooks, and routing. Let's break down the steps to build this application.
Step 1: Setting Up the Project
First, we need to set up our React environment. You can use Create React App to bootstrap your application:
npx create-react-app task-manager
cd task-manager
npm start
This will create a new React application in a folder named task-manager and start the development server.
Step 2: Structuring the Application
Next, let's structure our application. We will create the following components:
- App: The main component that holds the application.
- TaskList: A component that displays a list of tasks.
- Task: A component that represents an individual task.
- TaskForm: A component for adding new tasks.
Create a folder named components in the src directory and create the following files:
- App.js
- TaskList.js
- Task.js
- TaskForm.js
Step 3: Implementing the Components
App Component
The App component will manage the state of our tasks and render the TaskList and TaskForm components.
import React, { useState } from 'react';
import TaskList from './components/TaskList';
import TaskForm from './components/TaskForm';
const App = () => {
const [tasks, setTasks] = useState([]);
const addTask = (task) => {
setTasks([...tasks, task]);
};
const deleteTask = (taskId) => {
setTasks(tasks.filter((task) => task.id !== taskId));
};
return (
<div>
<h1>Task Manager</h1>
<TaskForm addTask={addTask} />
<TaskList tasks={tasks} deleteTask={deleteTask} />
</div>
);
};
export default App;
In this code:
- We import useState from React to manage our tasks.
- The addTask function updates the tasks state with a new task.
- The deleteTask function removes a task based on its id.
- We render the TaskForm and TaskList components, passing down necessary props.
TaskForm Component
The TaskForm component will handle the input for new tasks and submit them:
import React, { useState } from 'react';
const TaskForm = ({ addTask }) => {
const [taskName, setTaskName] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (!taskName) return;
const newTask = { id: Date.now(), name: taskName, completed: false };
addTask(newTask);
setTaskName('');
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={taskName}
onChange={(e) => setTaskName(e.target.value)}
placeholder="Add a new task"
/>
<button type="submit">Add Task</button>
</form>
);
};
export default TaskForm;
In this code:
- We maintain a local state for the task name using useState.
- The handleSubmit function creates a new task and calls addTask to update the tasks in the App component.
TaskList Component
The TaskList component will render all tasks and provide a way to delete them:
import React from 'react';
import Task from './Task';
const TaskList = ({ tasks, deleteTask }) => {
return (
<ul>
{tasks.map((task) => (
<Task key={task.id} task={task} deleteTask={deleteTask} />
))}
</ul>
);
};
export default TaskList;
This component maps over the array of tasks and renders a Task component for each one, passing down the necessary props.
Task Component
The Task component will display individual task details:
import React from 'react';
const Task = ({ task, deleteTask }) => {
return (
<li>
<span>{task.name}</span>
<button onClick={() => deleteTask(task.id)}>Delete</button>
</li>
);
};
export default Task;
In this code:
- We display the task name and provide a button to delete the task, which calls the deleteTask function passed from the TaskList component.
Step 4: Adding Styles
To make our application visually appealing, we can add some basic CSS. Create a styles.css file in the src folder:
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
h1 {
text-align: center;
}
form {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
input {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
margin-right: 10px;
}
button {
padding: 10px;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background: white;
padding: 10px;
margin: 5px 0;
display: flex;
justify-content: space-between;
border-radius: 5px;
}
This CSS will style the body, headings, form, input fields, buttons, and task list items.
Step 5: Integrating API Calls (Optional)
For a more advanced feature, you can integrate an API to save and retrieve tasks. You can use a service like JSONPlaceholder or create your own backend using Node.js and Express. Here’s a simple example of how you might fetch tasks from an API:
import React, { useEffect, useState } from 'react';
const App = () => {
const [tasks, setTasks] = useState([]);
useEffect(() => {
const fetchTasks = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
const data = await response.json();
setTasks(data.slice(0, 10)); // Get first 10 tasks
};
fetchTasks();
}, []);
// ... rest of the component
};
In this code:
- We use the useEffect hook to fetch tasks from an API when the component mounts.
- The fetched tasks are then stored in the state.
Common Mistakes and How to Avoid Them
- Not managing state properly: Ensure that you are using
useStatecorrectly to manage the state of your tasks. Always update state immutably. - Forgetting to bind functions: If you are using class components (not in our case, but good to know), remember to bind your methods in the constructor.
- Neglecting component structure: Keep your components small and focused on a single responsibility to make them easier to maintain.
Best Practices
- Component Reusability: Design components that can be reused in different parts of your application.
- State Management: Keep your state as close to where it is needed as possible. Use context or state management libraries like Redux for more complex applications.
- Code Organization: Organize your components and styles logically to make your codebase easier to navigate.
Key Takeaways
- You have learned how to build a full-featured React application from scratch.
- You can effectively manage state and props in your components.
- You have experience with component composition and how to structure your application.
- You are familiar with basic styling and can enhance your application's UI.
- You have the option to integrate APIs for dynamic data handling.
Conclusion
Congratulations on reaching the end of this course! You have built a comprehensive React application and gained a solid understanding of React concepts. As you continue your journey in web development, remember to keep practicing and exploring more advanced topics. React has a vast ecosystem, and there is always more to learn. Good luck with your future projects!
Exercises
Exercises
- Modify the Task Component: Add a checkbox to mark tasks as completed. Update the UI to reflect the completed status.
- Add Task Editing: Implement functionality to edit an existing task. Create a new form that allows users to modify task details.
- Persist Tasks: Modify your application to persist tasks in local storage so that tasks remain after a page refresh.
- Add Filtering: Create a filter feature that allows users to view only completed or active tasks.
- Mini-Project: Enhance the Task Management Application by adding user authentication (e.g., using Firebase) and allowing users to register and log in to manage their own tasks.
Summary
- You have learned to build a full-featured React application.
- The application includes task management features such as adding, deleting, and viewing tasks.
- You have practiced using components, state, props, and hooks.
- You have learned about basic styling and can enhance your application's UI.
- You are aware of best practices and common mistakes in React development.