How to work with typescript and react and define props, state, functional component in react typescript application

Author
April 06, 2022

In this article i will explain you step by step how you can work with typescript in your react application i’m gonna create a todo app to demonstrate the various props, state, components in react typescript application

Step 1: Create a react typescript application

Use below command to create react typescript application in this command i have specified dot which means i’m going to create project in the same folder in which iam rather than creating a new folder

//create react typescript project in the same folder which you are in
npx create-react-app . --template typescript

//create a separate folder with the name my-app and create project inside that
npx create-react-app my-app --template typescript

Step 2: Create ToDoList component and css

  • In our newly created project just clean up the src/App.tsx file and remove any extra code just like below
import React from "react";

const App: React.FC = () => {
  return <div className="App"></div>;
};

export default App;
  • Create a folder src/components inside that folder create a file ToDoList.tsx i’m gonna create a todo list app to demonstarte you how you can work with typescript

  • Inside ToDoList.tsx copy paste the following code

import React from "react";

import "./ToDoList.css";

interface TodoListProps {
  items: { id: string, text: string }[];
  onDeleteTodo: (id: string) => void;
}

const TodoList: React.FC<TodoListProps> = (props) => {
  return (
    <ul>
      {props.items.map((todo) => (
        <li key={todo.id}>
          <span>{todo.text}</span>
          <button onClick={props.onDeleteTodo.bind(null, todo.id)}>
            DELETE
          </button>
        </li>
      ))}
    </ul>
  );
};

export default TodoList;
  • In above code i have defined functional component prop types and passed prop types as generic types to react functional component

  • This is prop type which i have defined which this functional component will recieve which consist of array items and onDeleteTodo function

interface TodoListProps {
  items: { id: string, text: string }[];
  onDeleteTodo: (id: string) => void;
}
  • Create a file ToDoList.css and copy paste the following code
ul {
  list-style: none;
  width: 90%;
  max-width: 40rem;
  margin: 2rem auto;
  padding: 0;
}

li {
  margin: 1rem 0;
  padding: 1rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
  border-radius: 6px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

Step 3 Create NewToDo components and css

  • Create file *src/components/NewToDo.tsx and src/components/NewToDo.css

  • Copy paste below code inside NewToDo.tsx file

import React, { useRef } from "react";

import "./NewToDo.css";

type NewTodoProps = {
  onAddTodo: (todoText: string) => void;
};

const NewTodo: React.FC<NewTodoProps> = (props) => {
  const textInputRef = useRef<HTMLInputElement>(null);

  const todoSubmitHandler = (event: React.FormEvent) => {
    event.preventDefault();
    const enteredText = textInputRef.current!.value;
    props.onAddTodo(enteredText);
  };

  return (
    <form onSubmit={todoSubmitHandler}>
      <div className="form-control">
        <label htmlFor="todo-text">Todo Text</label>
        <input type="text" id="todo-text" ref={textInputRef} />
      </div>
      <button type="submit">ADD TODO</button>
    </form>
  );
};

export default NewTodo;
  • In above function i have created prop types which will recieve a function onAddToDo

  • Copy paste below css code inside NewToDo.css

form {
  width: 90%;
  max-width: 40rem;
  margin: 2rem auto;
}

.form-control {
  margin-bottom: 1rem;
}

label,
input {
  display: block;
  width: 100%;
}

label {
  font-weight: bold;
}

input {
  font: inherit;
  border: 1px solid #ccc;
  padding: 0.25rem;
}

input:focus {
  outline: none;
  border-color: #50005a;
}

button {
  background: #50005a;
  border: 1px solid #50005a;
  color: white;
  padding: 0.5rem 1.5rem;
  cursor: pointer;
}

button:focus {
  outline: none;
}

button:hover,
button:active {
  background: #6a0a77;
  border-color: #6a0a77;
}

Step 4 Call the components which we have created above inside App.tsx file

  • Copy paste below code inside your App.tsx file
import React, { useState } from "react";
// import { Route } from 'react-router-dom';

import TodoList from "./components/ToDoList";
import NewTodo from "./components/NewToDo";
import { Todo } from "./todo.model";

const App: React.FC = () => {
  const [todos, setTodos] = useState<Todo[]>([]);

  const todoAddHandler = (text: string) => {
    setTodos((prevTodos) => [
      ...prevTodos,
      { id: Math.random().toString(), text: text },
    ]);
  };

  const todoDeleteHandler = (todoId: string) => {
    setTodos((prevTodos) => {
      return prevTodos.filter((todo) => todo.id !== todoId);
    });
  };

  return (
    <div className="App">
      <NewTodo onAddTodo={todoAddHandler} />
      <TodoList items={todos} onDeleteTodo={todoDeleteHandler} />
    </div>
  );
};

export default App;
  • In above code i have declared a state variable with the name todos which gonna store our to do data and which is of type ToDo which is our model which we have created

    Create model file src/todo.model.ts and copy paste the following code

    export interface Todo {
      id: string;
      text: string;
    }
  • Then we have created two function with the name todoAddHandler and todoDeleteHandler which gonna called by child component respectively and will recieve argument

  • I have passed these function as props to our child component that is NewToDo and ToDoList

  • In above code you could see how we can define state, pass props and also define prop types