Building a Simple Task List App using Virtual DOM in React

Building a Simple Task List App using Virtual DOM in React

In this tutorial, we’ll create a simple Task List application using React to demonstrate the virtual DOM and its benefits. The app will allow users to add tasks and mark them as complete.

Understanding the Virtual DOM

The Virtual DOM (Document Object Model) is a lightweight, in-memory representation of the real DOM. It serves as a simplified version of the actual DOM, which React employs to carry out a process known as diffing (or reconciliation).

This process involves comparing the existing DOM structure with the new one before making changes to the actual DOM. By doing so, React minimizes the number of expensive DOM operations, resulting in improved performance.

How the Virtual DOM Operates

When the state or props of a React component change, React generates a new Virtual DOM. Subsequently, the library compares this new Virtual DOM with the existing Virtual DOM, creating a list of differences (referred to as “diffing”). React then applies these changes to the real DOM in an efficient and minimal way, enhancing performance.

The following steps outline this process in detail:

  • The component’s state or props undergo a change.
  • React constructs a new Virtual DOM based on the modified component.
  • React performs a comparison between the new and current Virtual DOMs (diffing).
  • React determines the least number of changes needed to update the actual DOM (forming a patch).
  • React applies the patch to the real DOM, updating only the essential parts.

Step 1: Set up the project

First, create a new React project using the following command:

npx create-react-app task-list

Next, navigate to the project directory and open the src folder:

cd task-list/src

Step 2: Create the Task List component

Create a new file called TaskList.js in the src folder, and add the following code:

import React, { useState } from 'react';

const TaskList = () => {
  const [tasks, setTasks] = useState([]);

  return (
    <div>
      <h1>Task List</h1>
      <ul>
        {tasks.map((task, index) => (
          <li key={index}>{task}</li>
        ))}
      </ul>
    </div>
  );
};

export default TaskList;

This component initializes an empty task list and renders it using the map function.

Step 3: Add tasks to the list

Update the TaskList component to allow users to add tasks:

import React, { useState } from 'react';

const TaskList = () => {
  const [tasks, setTasks] = useState([]);
  const [newTask, setNewTask] = useState('');

  const addTask = () => {
    setTasks([...tasks, newTask]);
    setNewTask('');
  };

  return (
    <div>
      <h1>Task List</h1>
      <input
        type="text"
        value={newTask}
        onChange={(e) => setNewTask(e.target.value)}
      />
      <button onClick={addTask}>Add Task</button>
      <ul>
        {tasks.map((task, index) => (
          <li key={index}>{task}</li>
        ))}
      </ul>
    </div>
  );
};

export default TaskList;

We’ve added an input field and a button to the component. Users can type a task in the input field and click the “Add Task” button to add it to the list.

Step 4: Mark tasks as complete

Now, let’s allow users to mark tasks as complete by clicking on them:

import React, { useState } from 'react';

const TaskList = () => {
  const [tasks, setTasks] = useState([]);
  const [newTask, setNewTask] = useState('');

  const addTask = () => {
    setTasks([...tasks, { text: newTask, completed: false }]);
    setNewTask('');
  };

  const toggleTaskCompletion = (index) => {
    const updatedTasks = tasks.map((task, i) => {
      if (i === index) {
        return { ...task, completed: !task.completed };
      }
      return task;
    });
    setTasks(updatedTasks);
  };

  return (
    <div>
      <h1>Task List</h1>
      <input
        type="text"
        value={newTask}
        onChange={(e) => setNewTask(e.target.value)}
      />
      <button onClick={addTask}>Add Task</button>
      <ul>
    {tasks.map((task, index) => (
      <li
        key={index}
        onClick={() => toggleTaskCompletion(index)}
        style={{ textDecoration: task.completed ? 'line-through' : 'none' }}
      >
        {task.text}
      </li>
    ))}
  </ul>
</div>
);
};

export default TaskList;

In this step, we updated the task list to store objects instead of strings, each with a text and completed property. We also added a toggleTaskCompletion function that updates the completed property of a task when it is clicked. The task’s text will be crossed out if it is marked as completed.

Here is a live demo of the app hosted on CodeSandbox:

Step 5: Observe the benefits of the virtual DOM

Now that our Task List application is complete, we can observe how the virtual DOM benefits its performance:

  1. When a task is added, React updates the virtual DOM with the new task.
  2. React compares the new virtual DOM with the current virtual DOM, identifying the changes (in this case, the added task in the list).
  3. React calculates the minimum number of changes required to update the actual DOM, creating a patch.
  4. React applies the patch to the actual DOM, updating only the necessary parts (the list of tasks).

Similarly, when a task is marked as complete:

  1. React updates the virtual DOM with the new task state.
  2. React compares the new virtual DOM with the current virtual DOM, identifying the changes (in this case, the updated task style).
  3. React calculates the minimum number of changes required to update the actual DOM, creating a patch.
  4. React applies the patch to the actual DOM, updating only the necessary parts (the task’s style).

By minimizing the number of DOM updates, the virtual DOM provides improved performance, a simplified programming model, and optimized rendering for our Task List application.

Step 6: Integrate the Task List component into the main application

Now, let’s integrate the TaskList component into the main application. Open the src/App.js file and replace its contents with the following code:

import React from 'react';
import TaskList from './TaskList';

const App = () => {
  return (
    <div className="App">
      <TaskList />
    </div>
  );
};

export default App;

We’ve imported the TaskList component and included it in the App component. This ensures that our Task List is rendered when the application is run.

Step 7: Run the application

To run the application, open a terminal, navigate to the project directory, and enter the following command:

npm start

The application will open in your default web browser, and you can interact with the Task List by adding tasks and marking them as complete.

Conclusion

In this tutorial, we’ve built a simple Task List application using React to demonstrate the virtual DOM and its benefits. By leveraging the virtual DOM, React minimizes the number of costly DOM updates, improving performance and providing a simplified programming model. This results in a more efficient and smoother user experience.

You can further expand this application by implementing features such as task deletion, task editing, or filtering tasks based on their completion status. As you continue to work with React and the virtual DOM, you’ll be able to create even more complex and high-performing applications.

Previous Post

5 Tips for Detecting an Image Generated by AI

Next Post
AI Tools for Translation & Transcripts

8 AI Tools for Translation & Transcripts

Related Posts