스파르타코딩클럽 내일배움캠프 TIL29

한재창·2022년 12월 9일
0

TodoList ReFactoring

1. 폴더구성

  • 원장튜터님께 내가 작성한 코드 리뷰를 부탁드렸는데, 보완할 점과 아쉬운 부분들을 말씀해주시고 그에 대해 수정을 한 번 해보라고 숙제를 내주셨다.
  • 그 중 하나가 폴더구성을 깔끔하게 바꾸는 것이었는데 컴포넌트를 다시 짜보았다.
    • CSS 적용을 위해 폴더로 나누어 주었다.
    • 각 폴더에는 jsx, css 파일이 있는데 폴더안 jsx에서 사용한 것들만 css로 적용했다.
    • 자식 컴포넌트 파일은 하위폴더로 지정해주었다.

2. App.jsx

  • 수정한 부분 없다!

3. App.css

  • css를 나눠주고 App.css에 모든 파일들을 import 하는 형식을 썼다.
@import url("./components/TodoHeader/TodoHeader.css");
@import url("./components/TodoBoard/TodoInput/TodoInput.css");
@import url("./components/TodoBoard/TodoList/TodoList.css");
@import url("./components/TodoBoard/TodoList/TodoItem/TodoItem.css");

.wrap {
  max-width: 1200px;
  min-height: 800px;
  margin: 0 auto;
}

4. TodoHeader.jsx

  • 수정한 부분 없다!

5. TodoBoard.jsx

  • 이 파일에서 수정된 부분은 TodoList 부분을 컴포넌트로 나누어준 것이다.
  • 컴포넌트를 만들고 자식 파일에 props를 보내주었다.
import React, { useEffect, useState } from "react";
import TodoItem from "./TodoList/TodoItem/TodoItem";
import TodoInput from "./TodoInput/TodoInput";
import TodoList from "./TodoList/TodoList";

export default function TodoBoard() {
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    fetch("db/todo.json")
      .then((res) => res.json())
      .then((data) => setTodos(data));
  }, []);

  const deleteTodoHandler = (id) => {
    const newTodoList = todos.filter((todo) => todo.id !== id);
    setTodos(newTodoList);
  };

  return (
    <div>
      <TodoInput todos={todos} setTodos={setTodos} />
      // <<<<<<<<<<<<< 수정된 부분 >>>>>>>>>>>>>>>
      <TodoList
        todos={todos}
        deleteTodoHandler={deleteTodoHandler}
        setTodos={setTodos}
        isWorking={true}
      />
      <TodoList
        todos={todos}
        deleteTodoHandler={deleteTodoHandler}
        setTodos={setTodos}
        isWorking={false}
      />
        // <<<<<<<<<<<< 수정된 부분 >>>>>>>>>>>>>
    </div>
  );
}

6.TodoList.jsx

  • 전에 없었던 완전히 새로 만든 파일이다.
  • isWorking 이라는 props 를 받아와 true면 "Working.. 🔥" false면 "Done..🎉" 을 화면에 출력해준다.
  • 원장님이 내주신 숙제
    • map을 돌린 후 삼항 연산자로 화면을 나타내기 전에 filter로 한 번 걸러주기
    • todo.isDone true면 isWorking 에 출력
    • todo.isDone false면 Done 에 출력
    • 맨 처음에 에러가 떴는데 맵 뒤에도 삼항연산자를 써서 그랬다.
import React from "react";
import TodoItem from "./TodoItem/TodoItem";
export default function TodoList({
  todos,
  deleteTodoHandler,
  setTodos,
  isWorking,
}) {
  return (
    <div>
      <h1>{isWorking ? "Working.. 🔥" : "Done..🎉"}</h1>
      <div className="wrap-list">
        {todos
          .filter((todo) => (todo.isDone ? isWorking : !isWorking))
          .map((todo) => (
            <TodoItem
              key={todo.id}
              id={todo.id}
              title={todo.title}
              text={todo.text}
              isdone={todo.isDone}
              deleteTodoHandler={deleteTodoHandler}
              todos={todos}
              setTodos={setTodos}
            />
          ))}
      </div>
    </div>
  );
}

7. TodoItem

  • 아이디를 uuidv4() 로 랜덤 생성해주니 숫자가 아닌 문자열이 되었다.
  • 그 부분을 Number() 가 아닌 toString() 로 수정해주니 정상 작동하였다.
 const changeIsDone = (event) => {
    const newTodos = [];
    todos.forEach((todo) => {
      console.log(todo);
      if (todo.id.toString() === event.target.value) {
        newTodos.push({ ...todo, isDone: !todo.isDone });
      } else {
        newTodos.push({ ...todo });
      }
    });
    setTodos(newTodos);

8. TodoInput

  • 아이디를 생성할때 uuidv4() 형식을 사용하는 것으로 수정하였다.
    • 사용방법 : 터미널에서 npm add uuid
  • 제목이나 내용이 빈 칸이거나 아무 내용없이 띄어쓰기만 했다면 경고문을 작동
import React, { useState } from "react";
import { v4 as uuidv4 } from "uuid";

export default function TodoInput({ todos, setTodos }) {
  const [titleValue, setTitleValue] = useState("");
  const [textValue, setTextValue] = useState("");

  const onsubmit = (e) => {
    e.preventDefault();
    const newTodo = {
      id: uuidv4(),
      title: titleValue,
      text: textValue,
      isDone: true,
    };
    if (titleValue.trim() === "" || textValue.trim() === "")
      return alert("빈 칸을 채워주세요.");
    setTodos([...todos, newTodo]);
    setTitleValue("");
    setTextValue("");
  };
  return (
    <form className="form" onSubmit={onsubmit}>
      <div className="form-input">
        <label className="form-label" htmlFor="title">
          제목{" "}
        </label>
        <input
          className="input"
          id="title"
          value={titleValue}
          type="text"
          onChange={(event) => setTitleValue(event.target.value)}
        />
        <label className="form-label" htmlFor="text">
          내용{" "}
        </label>
        <input
          className="input"
          id="text"
          value={textValue}
          type="text"
          onChange={(event) => setTextValue(event.target.value)}
        />
      </div>
      <button className="form-button">Click</button>
    </form>
  );
}

9. 느낀점

  • 내가 원했던 것이 이렇게 깔끔하게 컴포넌트를 나누는 것이었는데 코드리뷰를 받길 잘했다고 생각한다.
    = 그런데 저것도 깔끔하게 나눈 것인지 지금보니 불문명하다.
  • 원장님이 내주신 숙제 덕분에 더 성장한 것을 느낀다.
  • 강의에서 본 내용을 활용할 수 있어서 좋았다. trim 메서드 사용^^
profile
취준 개발자

0개의 댓글