DEV Community

Cover image for My React Journey: Day 28
Ayoola Damilare
Ayoola Damilare

Posted on

My React Journey: Day 28

Building a To-Do List in React

Today, I worked on a React project to create a simple yet powerful To-Do List App. This project deepened my understanding of React hooks, state management, and event handling while allowing me to enhance the functionality with additional features like moving tasks up or down.

Here’s a breakdown of what I learned and implemented.

1. Setting Up the Component
I structured my ToDoList.jsx to use the useState hook for managing tasks. This allowed me to dynamically update and render the task list. Below is the basic setup for managing tasks:

import React, { useState } from 'react';

export default function ToDoList() {
  const [tasks, setTasks] = useState([]);
  const [newTask, setNewTask] = useState("");

  function handleInputChange(event) {
    setNewTask(event.target.value); // Enables us to see what we type
  }

  function addTask() {
    if (newTask.trim() !== "") {
      setTasks(t => [...t, newTask]); // Adds the new task to the task list
      setNewTask(""); // Resets the input field
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Adding and Deleting Tasks
I learned how to manipulate state to add and delete tasks. The addTask function checks if the input is valid before adding it, while deleteTask removes a specific task based on its index:

function deleteTask(index) {
  const updatedTasks = tasks.filter((_, i) => i !== index); // Removes the task at the given index
  setTasks(updatedTasks);
}
Enter fullscreen mode Exit fullscreen mode

3. Moving Tasks Up and Down
A key enhancement to the project was implementing task reordering. The moveTaskUp and moveTaskDown functions rearrange tasks based on their indices:

function moveTaskUp(index) {
  if (index > 0) {
    const updatedTasks = [...tasks];
    [updatedTasks[index], updatedTasks[index - 1]] = [updatedTasks[index - 1], updatedTasks[index]];
    setTasks(updatedTasks);
  }
}

function moveTaskDown(index) {
  if (index < tasks.length - 1) {
    const updatedTasks = [...tasks];
    [updatedTasks[index], updatedTasks[index + 1]] = [updatedTasks[index + 1], updatedTasks[index]];
    setTasks(updatedTasks);
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Adding Styles with CSS
To make the app visually appealing, I applied custom styles in index.css. Here are some of the highlights:

Button Styling:

button {
  font-size: 1.7rem;
  font-weight: bold;
  padding: 10px 20px;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.5s ease;
}
.add-button {
  background-color: hsl(125, 47%, 54%);
}
.add-button:hover {
  background-color: hsl(125, 47%, 44%);
}
Enter fullscreen mode Exit fullscreen mode

Task Item Styling:

li {
  font-size: 2rem;
  font-weight: bold;
  padding: 15px;
  background-color: hsl(0, 0%, 97%);
  margin-bottom: 10px;
  border: 3px solid hsla(0, 0%, 85%, 0.75);
  border-radius: 5px;
  display: flex;
  align-items: center;
}
Enter fullscreen mode Exit fullscreen mode

5. Complete To-Do List in Action
Here’s how everything comes together in the ToDoList.jsx component:

return (
  <div className='to-do-list'>
    <h1>To-Do List</h1>
    <div>
      <input 
        type='text'
        placeholder='Enter a task...'
        value={newTask}
        onChange={handleInputChange}
      />
      <button className='add-button' onClick={addTask}>
        Add
      </button>
    </div>

    <ol>
      {tasks.map((task, index) => (
        <li key={index}>
          <span className='text'>{task}</span>
          <button className='delete-button' onClick={() => deleteTask(index)}>Delete</button>
          <button className='move-button' onClick={() => moveTaskUp(index)}>☝️</button>
          <button className='move-button' onClick={() => moveTaskDown(index)}>πŸ‘‡</button>
        </li>
      ))}
    </ol>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  1. React Hooks: The useState hook is an efficient way to manage local component states.
  2. Event Handling: Functions like handleInputChange, addTask, and deleteTask showcase how user interactions can update the UI.
  3. Dynamic List Rendering: Using map to iterate over tasks makes the app dynamic and responsive to changes.
  4. Styling Best Practices: Combining CSS hover effects and transitions enhances user experience.

One step at a time

Source Code
You can access the full source code for this project on GitHub:
πŸ‘‰ To-Do List React App Repository

Feel free to explore, fork, and contribute to the project!

Top comments (0)