Здравствуйте, дорогие разработчики, в этом блоге мы создадим простое приложение для списка дел в React. Начнем с создания реактивного проекта.

npx create-react-app to-do-list

Позвольте мне сначала показать структуру папок.

//todolist.js

import './ToDoList.css'
import {  useState } from 'react'

const ToDoList = () => {

    const [task, setTask] = useState();
    const [taskArray, setTaskArray] = useState([]);

    const addItem = () => {
        if (!task) {
            alert('Please fill field');
        } else {
            setTaskArray([...taskArray, task]);
        }
        setTask('');
    }

    const removeItem = (id) => {
        const updatedTasks = taskArray.filter((elem, ind) => {
            return ind !== id;
        })
        setTaskArray(updatedTasks);
    }

    return (
        <>
            <div className="app-container" id="taskList">
                <h1 className="app-header">TO DO LIST</h1>
                <div className="add-task">
                    <input type="text" autoComplete="off" placeholder="Add New Task" v-model="tasks.name" className="task-input" value={task} onChange={(e) => setTask(e.target.value)} />
                    <input className="submit-task" title="Add Task" onClick={addItem} />
                </div>
                <div>
                    <ul className="task-list">
                        {
                            taskArray.map((val, ind) => {
                                return (
                                    <li className="task-list-item" v-for="task in tasks" key={ind}>
                                        <label className="task-list-item-label">
                                            <input type="checkbox" />
                                            <span>
                                                {val}
                                            </span>
                                        </label>
                                        <span className="delete-btn" onClick={() => removeItem(ind)}></span>
                                    </li>
                                )
                            })
                        }
                    </ul>
                </div>
            </div>
        </>
    )
}

export default ToDoList
//toDoList.css

@import url("https://fonts.googleapis.com/css?family=DM+Sans:400,500,700&display=swap");

* {
  box-sizing: border-box;
}

:root {
  --checkbox-color: #ee9ca7;
  --checkbox-shadow: rgba(238, 156, 167, 0.2);
  --add-button: #ee9ca7;
  --add-button-shadow: rgba(238, 156, 167, 0.4);
}

body {
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 16px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-image: linear-gradient(
      62deg,
      rgba(1, 95, 183, 0.9732216701) 13%,
      rgba(255, 122, 151, 0.5) 4%
    ),
    linear-gradient(
      44deg,
      rgba(0, 43, 99, 0.0792209024) 39%,
      rgba(242, 140, 143, 0.5) 18%
    ),
    linear-gradient(
      118deg,
      rgba(84, 202, 242, 0.0315299727) 40%,
      rgba(247, 155, 187, 0.5) 54%
    ),
    linear-gradient(
      58deg,
      rgba(90, 90, 237, 0.1614444357) 83%,
      rgba(249, 156, 142, 0.5) 23%
    );
  background-blend-mode: normal, lighten, multiply, hard-light;
  font-family: "DM Sans", sans-serif;
  overflow: hidden;
}

input {
  outline: none;
}

ul {
  list-style: none;
  padding: 0;
}

.app-container {
  border-radius: 8px;
  width: 100%;
  max-width: 480px;
  max-height: 100%;
  background-color: #10101d;
  padding: 24px;
  overflow: auto;
}

.app-header {
  font-size: 20px;
  line-height: 32px;
  margin: 0 0 12px 0;
  color: #fff;
}

.submit-task {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: none;
  background: var(--add-button);
  color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-plus'%3E%3Cline x1='12' y1='5' x2='12' y2='19'/%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3C/svg%3E");
  background-size: 18px;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 12px 0 var(--add-button-shadow);
}

.add-task {
  height: 40px;
  font-size: 14px;
  display: flex;
}

.task-input {
  border-right: none;
  width: 100%;
  padding: 0 4px;
  outline: none;
  border: none;
  border-bottom: 1px solid #fff;
  background-color: transparent;
  margin-right: 12px;
  color: #fff;
  box-shadow: none;
  border-radius: 0;
}

.task-input:placeholder {
  color: #fff;
}

.task-list-item {
  background-color: #191933;
  border-radius: 4px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  padding: 8px;
}

.task-list-item input {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-check' stroke='%23fff'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0;
  transition: 0.2s;
  margin-right: 8px;
  flex-shrink: 0;
  margin-top: 4px;
  appearance: none;
}

.task-list-item input:hover {
  border-color: var(--checkbox-color);
  box-shadow: 0 0 0 3px var(--checkbox-shadow);
}

.task-list-item input:checked {
  background-size: 10px;
  border: 1px solid var(--checkbox-color);
  background-color: var(--checkbox-color);
}

.task-list-item input:checked + span {
  color: rgba(255, 255, 255, 0.5);
  text-decoration: line-through rgba(255, 255, 255, 0.8);
}

.task-list-item-label {
  display: flex;
  align-items: flex-start;
  color: #fff;
  margin-right: 8px;
  font-size: 14px;
  line-height: 24px;
  position: relative;
  transition: 0.2s;
  cursor: pointer;
}

.delete-btn {
  margin-left: auto;
  display: block;
  width: 16px;
  height: 16px;
  background-repeat: no-repeat;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23ff3d46' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-trash-2'%3E%3Cpolyline points='3 6 5 6 21 6'/%3E%3Cpath d='M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2'/%3E%3Cline x1='10' y1='11' x2='10' y2='17'/%3E%3Cline x1='14' y1='11' x2='14' y2='17'/%3E%3C/svg%3E");
  background-size: 16px;
  background-position: center;
  cursor: pointer;
}

@supports (-webkit-appearance: none) or (-moz-appearance: none) {
  input[type="checkbox"],
  input[type="radio"] {
    -webkit-appearance: none;
    -moz-appearance: none;
  }
}
//App.js

import './App.css';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.js';
import ToDoList from './Todolist';


function App() {
  return (
    <div className="App">
      <ToDoList />
    </div>
  );
}

export default App;

Исходный код: https://github.com/AwinashGoswami/Todolist-React