Building a Todo Web Application with React
Objective
Create a functional todo list application using React.js. This project focuses on learning core React concepts by building a practical application that manages tasks, demonstrating component creation, state management, and user interactions through a hands-on approach.
Learning Outcomes
By completing this project, you will:
- Master React fundamentals through practical application.
- Learn state management using both hooks and class components.
- Understand component architecture and data flow.
- Implement user interactions and event handling.
- Practice styling with modern CSS frameworks.
Prerequisites and Theoretical Foundations
1. Basic Web Development Skills
- HTML/CSS: Understanding of web markup and styling.
- JavaScript: Familiarity with ES6+ features.
- DOM Manipulation: Basic understanding of browser events.
2. Development Environment
- Node.js: Basic knowledge of npm and package management.
- Code Editor: Experience with VS Code or similar editors.
- Terminal: Basic command line operations.
3. React Fundamentals
- Components: Understanding of component-based architecture.
- Props: Knowledge of data passing between components.
- State: Basic understanding of component state.
Tools Required
- Programming Environment:
- Node.js and npm installed
- Visual Studio Code or preferred IDE
- Core Dependencies:
- Create React App (
npx create-react-app
) - React Bootstrap (
npm install react-bootstrap bootstrap
) - Material UI (
npm install @mui/material @emotion/react @emotion/styled
)
- Create React App (
- Development Tools:
- Chrome DevTools with React Developer Tools extension
- Git for version control
Project Structure
todo-app/
│
├── src/
│ ├── components/
│ │ ├── Layout.js
│ │ ├── Header.js
│ │ ├── TodoApp.js
│ │ └── MainContent.js
│ ├── styles/
│ │ └── styles.css
│ ├── App.js
│ └── index.js
│
└── public/
└── index.html
Steps and Tasks
1. Setting Up the Development Environment
Tasks:
- Install Required Tools.
- Create New React Project.
- Install Dependencies.
Implementation:
# Install Create React App globally
npm install -g create-react-app
# Create new React project
npx create-react-app todo-app
cd todo-app
# Install additional dependencies
npm install react-bootstrap bootstrap
npm install @mui/material @emotion/react @emotion/styled
2. Creating the Basic Layout Component
Tasks:
- Create Layout Structure.
- Implement Header and Footer.
- Set Up Main Content Area.
Implementation:
// src/components/Layout.js
import React from 'react';
import Header from './Header';
import MainContent from './MainContent';
import './styles/styles.css';
const Layout = ({ title }) => {
return (
<div className="app-container">
<Header title={title} />
<MainContent />
<footer className="footer">
<p>My Todo App - Built with React</p>
</footer>
</div>
);
};
// src/components/Header.js
const Header = ({ title }) => {
return (
<header className="header">
<h1>{title}</h1>
</header>
);
};
export default Layout;
3. Implementing the Todo Component
Tasks:
- Create Todo Class Component.
- Implement State Management.
- Add Task Management Functions.
Implementation:
// src/components/TodoApp.js
import React, { Component } from 'react';
import { Button, Form, ListGroup } from 'react-bootstrap';
class TodoApp extends Component {
constructor(props) {
super(props);
this.state = {
tasks: [],
newTask: ''
};
}
handleChange = (e) => {
this.setState({ newTask: e.target.value });
};
handleSubmit = (e) => {
e.preventDefault();
if (this.state.newTask.trim()) {
this.setState(prevState => ({
tasks: [...prevState.tasks, this.state.newTask],
newTask: ''
}));
}
};
handleDelete = (index) => {
this.setState(prevState => ({
tasks: prevState.tasks.filter((_, i) => i !== index)
}));
};
render() {
return (
<div className="todo-container">
<Form onSubmit={this.handleSubmit}>
<Form.Group className="mb-3">
<Form.Control
type="text"
value={this.state.newTask}
onChange={this.handleChange}
placeholder="Enter a new task"
/>
</Form.Group>
<Button variant="primary" type="submit">
Add Task
</Button>
</Form>
<ListGroup className="mt-3">
{this.state.tasks.map((task, index) => (
<ListGroup.Item key={index} className="d-flex justify-content-between">
{task}
<Button
variant="danger"
size="sm"
onClick={() => this.handleDelete(index)}
>
Delete
</Button>
</ListGroup.Item>
))}
</ListGroup>
</div>
);
}
}
export default TodoApp;
4. Styling the Application
Tasks:
- Create Base Styles.
- Implement Responsive Design.
- Add Visual Enhancements.
Implementation:
/* src/styles/styles.css */
.app-container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.header {
background-color: #f8f9fa;
padding: 20px;
text-align: center;
margin-bottom: 20px;
border-radius: 5px;
}
.todo-container {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.footer {
margin-top: 20px;
text-align: center;
padding: 20px;
background-color: #f8f9fa;
border-radius: 5px;
}
.list-group-item {
margin-bottom: 5px;
transition: background-color 0.2s ease;
}
.list-group-item:hover {
background-color: #f8f9fa;
}
5. Integrating Components
Tasks:
- Connect Components Together.
- Set Up Props Flow.
- Implement Data Management.
Implementation:
// src/App.js
import React from 'react';
import Layout from './components/Layout';
import TodoApp from './components/TodoApp';
import 'bootstrap/dist/css/bootstrap.min.css';
function App() {
return (
<Layout title="My Todo App">
<TodoApp />
</Layout>
);
}
export default App;
6. Adding Final Touches
Tasks:
- Implement Error Handling.
- Add Loading States.
- Include User Feedback.
Implementation:
// Enhanced TodoApp component with error handling and feedback
import React, { Component } from 'react';
import { Button, Form, ListGroup, Alert } from 'react-bootstrap';
class TodoApp extends Component {
constructor(props) {
super(props);
this.state = {
tasks: [],
newTask: '',
error: null,
isLoading: false
};
}
handleSubmit = async (e) => {
e.preventDefault();
this.setState({ isLoading: true, error: null });
try {
if (!this.state.newTask.trim()) {
throw new Error('Task cannot be empty');
}
this.setState(prevState => ({
tasks: [...prevState.tasks, this.state.newTask],
newTask: '',
error: null
}));
} catch (error) {
this.setState({ error: error.message });
} finally {
this.setState({ isLoading: false });
}
};
// ... rest of the component implementation
}
Further Enhancements
-
Data Persistence:
- Implement local storage
- Add backend integration
-
Task Features:
- Add due dates
- Include priority levels
- Support task categories
-
User Experience:
- Add drag-and-drop reordering
- Implement task filtering
- Add search functionality
-
Authentication:
- Add user accounts
- Implement task sharing
Conclusion
This project demonstrates:
- Core React concepts through practical implementation
- Component-based architecture in a real application
- State management techniques
- User interaction handling
- Styling and UI best practices
The todo application serves as a foundation for learning React while building a practical, useful application that can be extended with more features.