Learn TypeScript with React By Building a CRUD Application
Tags: typescript, react, crud, application
Published: 2023-02-23 07:41:06

TypeScript is a powerful programming language that enhances the development of complex web applications by adding a static type system to JavaScript. React is a popular JavaScript library used for building user interfaces. Combining these two technologies can take your web development to the next level. 

If you want to refer the code for this entire project, you can download it from [here](https://mobisoftinfotech.com/resources/blog/learn-typescript-with-react-by-building-a-crud-application/).
Setup your development environment

Install Node.js and npm (Node Package Manager) if you haven't already done so
Create a new React project using create-react-app
Install the necessary dependencies:

```
npm install --save typescript @types/react @types/react-dom @types/node
```
Rename the src/index.js file to src/index.tsx
Update the scripts section in package.json to use TypeScript:

```
"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject",
  "start:ts": "react-scripts start --template typescript",
  "build:ts": "react-scripts build --template typescript",
  "test:ts": "react-scripts test --template typescript"
}
```
Define the data model and create the API

Define the interface for the data model in src/models/todo.ts

```
export interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

```
Create a mock API to simulate fetching and updating data in src/services/todo.ts

```
import { Todo } from '../models/todo';

let todos: Todo[] = [
  { id: 1, title: 'Buy milk', completed: false },
  { id: 2, title: 'Walk the dog', completed: true },
  { id: 3, title: 'Finish the project', completed: false },
];

export function getTodos(): Promise<Todo[]> {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(todos);
    }, 500);
  });
}

export function saveTodo(todo: Todo): Promise<Todo> {
  return new Promise(resolve => {
    setTimeout(() => {
      const index = todos.findIndex(t => t.id === todo.id);
      if (index === -1) {
        todos.push(todo);
      } else {
        todos[index] = todo;
      }
      resolve(todo);
    }, 500);
  });
}

export function deleteTodo(id: number): Promise<void> {
  return new Promise(resolve => {
    setTimeout(() => {
      todos = todos.filter(t => t.id !== id);
      resolve();
    }, 500);
  });
}

```
Create the components

Create the TodoList component in src/components/TodoList.tsx

```
import { useState, useEffect } from 'react';
import { Todo } from '../models/todo';
import { getTodos, saveTodo, deleteTodo } from '../services/todo';

function TodoList() {
  const [todos, setTodos] = useState<Todo[]>([]);

  useEffect(() => {
    getTodos().then(data => setTodos(data));
  }, []);

  function handleSave(todo: Todo) {
    saveTodo(todo).then(data => {
      const index = todos.findIndex(t => t.id === data.id);
      if (index === -1) {
        setTodos([...todos, data]);
      } else {
        todos[index] = data;
        setTodos([...todos]);
      }
    });
  }

  function handleDelete(id: number) {
    deleteTodo(id).then(() => {
      setTodos(todos.filter(t => t.id !== id));
    });
  }

  return (
    <div>
      <ul>
        {todos.map(todo

```