React Todo App with API

Summary: in this tutorial, you will continue integrating the React Todo App with the API server to store the todo list.

Setting up an API server

First, download the following file and extract it to a directory on your computer such as todo-api:

Download Todo API Server Source Code

Second, open your terminal and navigate to the project directory:

cd todo-apiCode language: JavaScript (javascript)

Third, run the following npm command to install project dependencies:

npm instalCode language: JavaScript (javascript)

Finally, run the npm start command to start the API server:

npm startCode language: JavaScript (javascript)

The API server will be running and listening on the port 5000:

http://localhost:5000/Code language: JavaScript (javascript)

The following table displays the API endpoints:

MethodEndpointDescriptionRequest BodyResponse
GET/todosRetrieve all todo items.NoneJSON array of todos
GET/todos/:idRetrieve a single todo item by its ID.NoneJSON object of the todo item
POST/todosCreate a new todo item.{ "title": string, "completed": integer }JSON object of the created todo item
PUT/todos/:idUpdate an existing todo item by its ID.{ "title": string, "completed": boolean }JSON object of the updated todo item
DELETE/todos/:idDelete a todo item by its ID.None{ "id": integer }

Integrating the API into the React Todo App

To call an API from React, you can use the built-in Fetch API provided by web browsers.

Displaying the todo list

When the Todo app starts for the first time, it should call the API GET /todos to retrieve all todo items and display them on the screen.

To do that, we need to:

  • Define a function getTodos that calls the API GET /todos to retrieve all todos items and update the todos state.
  • Execute the getTodos function only for the first time when the app starts.

First, define a new function getTodos() that calls the API and updates the todos state:

const getTodos = async () => {
    const url = 'http://localhost:5000/todos';
    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        throw new Error('Network response was not ok');
      }

      const storedTodos = await response.json();
      // Update the state
      if (storedTodos) setTodos(storedTodos);
    } catch (error) {
      console.error('Error during GET request:', error);
    }
  };Code language: JavaScript (javascript)

Second, call the getTodos() function once when the component renders for the first time using the useEffect() hook:

useEffect(() => {
  getTodos();
}, []);Code language: JavaScript (javascript)

In this syntax, the useEffect is a hook in React. A hook is a function that adds functionality to the component.

The useEffect() hook allows you to run a function at a specific point in time. It accepts two arguments:

  • A function
  • An empty array ([]).

The empty array instructs the useEffect() hook to execute the function the first time the component renders. We’ll cover more about React hooks in the upcoming tutorials.

Creating a new todo item

To create a new todo item, you need to:

  • Call the API POST /todos to create a new todo item in the database.
  • Add the new todo to the current todos state using the setTodos function.

Here’s the modified version of the createTodo() function:

const createTodo = async (title) => {
    // form a new todo
    const newTodo = {
      title: title,
      completed: false,
    };

    // call an API to create a new todo
    const url = 'http://localhost:5000/todos';
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(newTodo),
      });

      if (!response.ok) throw new Error('Network response was not ok');

      const storedTodo = await response.json();

      // set a new state
      const updatedTodos = [...todos, storedTodo];

      setTodos(updatedTodos);
    } catch (error) {
      console.error('Error creating a todo:', error);
    }
  };Code language: JavaScript (javascript)

Removing a todo item

To remove a todo item, you need to:

  • Call the API DELETE /todo/:id to delete a todo specified by the ID from the database.
  • Remove the deleted todo from the todos state.

Here’s the new version of the removeTodo() function:

const removeTodo = async (id) => {
    // Delete the todo
    const url = `http://localhost:5000/todos/${id}`;

    try {
      const response = await fetch(url, {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) throw new Error('Network response was not ok');

      // Update the state
      const updatedTodos = todos.filter((todo) => todo.id !== id);
      setTodos(updatedTodos);
    } catch (error) {
      console.error('Error during DELETE request:', error);
      throw error;
    }
  };Code language: JavaScript (javascript)

Updating a todo item

To update a todo item, you need to:

  • Call the API PUT /todo/:id to update a todo specified by the id.
  • Update the modified todo in the todos state.

Here’s the new version of the changeTodo() function:

const changeTodo = async (id, newTitle, completed = false) => {
    // Update todo
    const url = `http://localhost:5000/todos/${id}`;

    const data = { title: newTitle, completed };

    try {
      const response = await fetch(url, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      });

      if (!response.ok) {
        throw new Error('Network response was not ok');
      }

      const updatedTodo = await response.json();

      // Update the state
      const updatedTodos = todos.map((todo) => {
        if (todo.id === id) {
          return { ...todo, ...updatedTodo };
        }
        return todo;
      });
      setTodos(updatedTodos);
    } catch (error) {
      console.error('Error during PUT request:', error);
      throw error;
    }
  };Code language: JavaScript (javascript)

The rest of the Todo app remains the same.

Download the React Todo App with API

Download the React Todo App with API Source Code

Summary

  • Use the Fetch API provided by the web browser to call APIs.
  • Use the useEffect hook to run a function once after the component is displayed.
Was this tutorial helpful ?