react tailwind todo app that uses fetch to fetch and add todo items in typescript

To create a React todo app that uses Tailwind CSS and typescript with fetch to fetch and add todo items, you can follow these steps:

  1. Create a new React project with Typescript in your preferred directory using the command npx create-react-app my-todo-app --template typescript.

  2. Install Tailwind CSS with the command npm install tailwindcss.

  3. Create a tailwind.config.js file with the command npx tailwindcss init.

  4. In the tailwind.config.js file, add the following lines at the end of the module.exports object:

module.exports = {
  // other options
  purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
230 chars
13 lines
  1. In the index.css file, add the following lines to import the Tailwind CSS:
@import './tailwind.css';
26 chars
2 lines
  1. Create a new file Todo.tsx in the src directory with the following contents:
import React, { useState, useEffect } from 'react';

interface TodoItem {
  id: number;
  text: string;
  completed: boolean;
}

const Todo = () => {
  const [todos, setTodos] = useState<TodoItem[]>([]);
  const [text, setText] = useState<string>('');

  useEffect(() => {
    fetchTodos();
  }, []);

  const fetchTodos = async () => {
    const res = await fetch('https://jsonplaceholder.typicode.com/todos');
    const json = await res.json();
    setTodos(json);
  };

  const addTodo = async () => {
    const newTodo = {
      id: todos.length + 1,
      text,
      completed: false,
    };
    const res = await fetch('https://jsonplaceholder.typicode.com/todos', {
      method: 'POST',
      body: JSON.stringify(newTodo),
      headers: {
        'Content-Type': 'application/json',
      },
    });
    if (res.ok) {
      const json = await res.json();
      setTodos([...todos, json]);
      setText('');
    }
  };

  const toggleTodo = async (id: number) => {
    const targetTodo = todos.find((todo) => todo.id === id);
    if (targetTodo) {
      const res = await fetch(
        `https://jsonplaceholder.typicode.com/todos/${id}`,
        {
          method: 'PATCH',
          body: JSON.stringify({
            completed: !targetTodo.completed,
          }),
          headers: {
            'Content-Type': 'application/json',
          },
        }
      );
      if (res.ok) {
        const json = await res.json();
        setTodos(
          todos.map((todo) => (todo.id === id ? json : todo))
        );
      }
    }
  };

  return (
    <div className="container mx-auto">
      <h1 className="text-3xl font-bold mb-4">Todo List</h1>
      <div className="flex">
        <input
          type="text"
          className="w-full px-2 py-1 text-gray-700 bg-gray-200 rounded mr-2"
          placeholder="Add a new todo..."
          value={text}
          onChange={(e) => setText(e.target.value)}
        />
        <button
          className="px-2 py-1 bg-blue-500 text-white rounded"
          onClick={addTodo}
        >
          Add
        </button>
      </div>
      <ul className="list-disc mt-4">
        {todos.map((todo) => (
          <li
            key={todo.id}
            className={`${
              todo.completed ? 'line-through text-green-500' : ''
            } cursor-pointer mb-2`}
            onClick={() => toggleTodo(todo.id)}
          >
            {todo.text}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Todo;
2500 chars
103 lines
  1. In the App.tsx file, replace the default contents with the following:
import React from 'react';

import Todo from './Todo';

const App = () => {
  return (
    <div className="bg-gray-100 min-h-screen py-8">
      <Todo />
    </div>
  );
};

export default App;
194 chars
14 lines
  1. Start the development server with the command npm start.

  2. Open your web browser and navigate to http://localhost:3000 to see the todo app in action.

gistlibby LogSnag