실습/React

[React/JavaScript] 투두 리스트(Todo-List) 만들기 (3)

이우열 2023. 12. 29. 23:58
728x90

 

CSS를 추가하여 투두 리스트를 꾸며봅시다.

 

✅ App.js 수정하기

import { useState } from "react";
import "./App.css";

function App() {
  const [toDo, setToDo] = useState("");
  const [toDos, setToDos] = useState([]);

  const onChange = (event) => {
    setToDo(event.target.value);
  };
  const onSubmit = (event) => {
    event.preventDefault();
    if (toDo.trim() !== "") {
      setToDos((currentArray) => [
        ...currentArray,
        { text: toDo, checked: false },
      ]);
      setToDo("");
    }
  };
  const onToggleCheck = (index) => {
    setToDos((currentArray) => {
      return currentArray.map((item, i) => {
        if (i === index) {
          return { ...item, checked: !item.checked };
        }
        return item;
      });
    });
  };
  const onRemove = (index) => {
    setToDos((currentArray) => currentArray.filter((_, i) => i !== index));
  };

  return (
    <>
      <h1 className="title">Todo List</h1>
      <form className="form-box" onSubmit={onSubmit}>
        <input
          id="todo"
          className="todo-input"
          type="text"
          value={toDo}
          onChange={onChange}
        />
        <button id="addBtn" className="add-btn" type="submit"></button>
      </form>
      <div id="todoBox" className="todo-box">
        {toDos.map((item, index) => (
          <label
            className={`new-todo ${item.checked ? "check" : ""}`}
            key={index}
          >
            {item.text}
            <input
              type="checkbox"
              checked={item.checked}
              onChange={() => onToggleCheck(index)}
            />
            <span className="check-mark"></span>
            <button className="rm-btn" onClick={() => onRemove(index)}></button>
          </label>
        ))}
      </div>
    </>
  );
}

export default App;

 

return 값인 html 태그들부터 수정 사항을 확인해봅시다.

  • ul 태그와 li 태그를 div 태그와 label 태그로 변경해줍니다.
  • label 태그 안에는 input 태그인 checkbox를 추가하고 체크박스를 커스텀하기 위해 span 태그를 추가해줍니다.

 

javascript 수정 사항을 확인해봅시다.

  • onSubmit 함수에서 새로운 할 일을 추가할 때 textchecked를 키로 갖는 객체를 추가해줍니다.

textinput에 입력한 toDo이며 checkedboolean 값으로 체크가 됐는지 확인하기 위한 변수입니다.

 

  • label에서 각 요소들이 checked 값이 true라면 "check" 클래스를 추가해줍니다.
  • input 태그에서는 checked 값이 item의 checked 값으로 연결되어 있고 체크박스의 값이 변경된다면 onToggledCheck 함수가 실행되도록 연결해줍니다

onToggledCheck 함수에서는 현재 toDos에서 선택된 index의 객체의 checked 값을 반대로 변경해줍니다.

 

 

✅ CSS 추가하기

자세한 CSS 설명은 다음 글을 참고하시면 됩니다.

 

https://w00ye0l.tistory.com/93

 

[JavaScript] 투두 리스트(Todo-List) 만들기 (3)

✅ CSS 추가 index.html에 class를 먼저 추가해줍시다. Todo List script.js 코드를 수정해줍시다. const todo = document.querySelector("#todo"); const addBtn = document.querySelector("#addBtn"); const todoBox = document.querySelector("#todo

w00ye0l.tistory.com

 

✏️ index.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  width: 100vw;
  height: 100vh;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: lightgray;
}

 

기본적인 index.css입니다.

 

✏️ App.css

.title {
  text-align: center;
  margin-bottom: 20px;
}

.form-box {
  display: flex;
  justify-content: space-between;
  width: 500px;
  height: 25px;
  margin-bottom: 10px;
}

.todo-input {
  width: 450px;
  border: 2px solid #000;
}

.add-btn {
  position: relative;
  width: 25px;
  height: 25px;
  border: 2px solid #000;
  background-color: #000;
  color: #fff;
  font-size: 25px;
  line-height: 25px;
  cursor: pointer;
}

.add-btn::after {
  position: absolute;
  display: inline-block;
  top: -1px;
  left: 3px;
  font-size: 25px;
  content: "\002B";
}

.todo-box {
  width: 500px;
  height: 400px;
  padding: 10px;
  border: 2px solid #000;
  background-color: #eee;
}

.new-todo {
  display: block;
  position: relative;
  height: 25px;
  padding-left: 35px;
  margin-bottom: 12px;
  cursor: pointer;
  font-size: 22px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  line-height: 25px;
}

.new-todo input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  cursor: pointer;
}

.check-mark {
  position: absolute;
  top: 0;
  left: 0;
  width: 25px;
  height: 25px;
  border: 2px solid #000;
  background-color: #fff;
}

.check {
  text-decoration: line-through;
}

.new-todo .check-mark::after {
  display: none;
  position: absolute;
  left: 7px;
  top: 3px;
  width: 5px;
  height: 10px;
  border: solid white;
  border-width: 0 3px 3px 0;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
  content: "";
}

.new-todo input:checked ~ .check-mark {
  background-color: #000;
}

.new-todo input:checked ~ .check-mark::after {
  display: block;
}

.rm-btn::after {
  position: absolute;
  right: 5px;
  top: 0px;
  display: inline-block;
  font-size: 30px;
  cursor: pointer;
  content: "\00d7";
}

.rm-btn:hover {
  color: red;
}

 

App.css입니다.

 

 

✅ 완성된 투두 리스트 결과

투두리스트 결과 화면

 

728x90