(6) Todo List 기본 기능 CRUD 추가 - 3 (삭제)

2023. 6. 8. 15:04Github 프로젝트/todolist반응형웹앱

728x90
반응형
SMALL

지난시간에는 갱신의 대해서 다뤄봤습니다.

갱신 부터 진행 후 다음은 삭제에 대해 다루겠습니다.

(5) Todo List 기본 기능 CRUD 추가 - 2 (갱신) : https://berkley.tistory.com/9

 

(5) Todo List 기본 기능 CRUD 추가 - 2 (갱신)

지난시간 CRUD의 읽기, 쓰기의 대해서 다뤄봤습니다. (4) Todo List 기본 기능 CRUD 추가 - 1 (읽기, 쓰기) : https://berkley.tistory.com/8 (4) Todo List 기본 기능 CRUD 추가 - 1 (읽기, 쓰기) 지난 시간 반응형 웹&앱 U

berkley.tistory.com

 

 

이어서, 각 기능별로 삭제에 대해 다루고자 합니다.

UI 부분은 차후 다룰 예정이니, 지금은 React를 이용한 프론트 엔드 개발이 목적이기 때문에 UI 부분은 무시하고 개발하겠습니다.

1. TodoList 삭제

 

이번 시간에는 삭제 기능을 추가하겠습니다.immutability-helper 로 이용하여 불변성을 유지하면서 원하는 배열을 삭제하는 형식으로 가겠습니다.

 

 

삭제 방법은 다음과 같습니다. update 메소드를 이용해서 todolist의 해당 배열 index부터 1개까지 제거 하라는 의미입니다.

  update(todoList, {
    $splice: [[index, 1]]
  })

 

 

이걸 반영을 하면 아래와 같이 메서드를 사용할 수 있습니다.

  // 삭제 관련 메소드 (제목)
  const removeTitle = (index) => {
    setTodoList(
      update(todoList, {
        $splice: [[index, 1]]
      })
    )
  }

 

 

웹 화면에 보여질 내용을 삭제 아이콘을 Button으로 추가하고, 기능을 추가합니다..

 

  <div className="todo">
    {
      // 다음은 각각 데이터를 불려올 때 map을 주로 사용합니다.
      // todoList에 저장된 state 값을
      // 유사 forEach문처럼 todo를 이용하여 출력하고,
      // 상위 div에 key값을 설정하기 위해 index 값을 집어 넣어야 합니다.
      todoList?.map((todo, index) => (
        <div key={index} className="todoContainer">
          <div className="todoTitle">
            {isTitleUpdate ? (
              <div>
                <Input
                  name="title"
                  defaultValue={todo?.title}
                  onChange={(e) => updateTitlOnChange(e, index)}
                />
                <Button onClick={() => updateTitle(index)}>
                  todolist수정
                </Button>
                <Button
                  onClick={() => setIsTitleUpdate(!isTitleUpdate)}
                >
                  취소
                </Button>
              </div>
            ) : (
              <div>
                {todo?.title}
                <Button
                  onClick={() => setIsTitleUpdate(!isTitleUpdate)}
                >
                  수정
                </Button>{" "}
                <PlusCircle />
                {/* 삭제 기능 추가*/}
                <Button onClick={() => removeTitle(index)}>
                  <Trash3 />
                </Button>
              </div>
            )}
          </div>

          {todo?.contents?.map((tc, tcIndex) => (
            <div key={tcIndex} className="todoContents">
              - {tc} <Trash3 />
            </div>
          ))}
        </div>
      ))
    }
  </div>

 

 

이에 따른 결과를 실행합니다.

 

<초기화면>

 

 

<JWT 인증 처리 제거 후 모습>

 

 

 

전체 코드 

import {
  Button,
  ButtonGroup,
  Card,
  CardBody,
  CardHeader,
  CardTitle,
  Form,
  Input,
} from "reactstrap";
import "./App.css";
import { PlusCircle, Trash3 } from "react-bootstrap-icons";
import { useEffect, useState } from "react";
import update from "immutability-helper";

function App() {
  /**
   * 필요 key:value값
   * title, contents
   * 이 값은
   */
  const [todoList, setTodoList] = useState([]);
  const [createInputTitle, setCreateInputTitle] = useState();
  // 갱신모드 설정
  const [isTitleUpdate, setIsTitleUpdate] = useState(false);

  // Todolist title 수정용 state
  const [changeTitle, setChangeTitle] = useState();

  useEffect(() => {
    setTodoList([
      {
        title: "Redux 학습하기",
        contents: [
          "로그인/로그아웃 가능 여부 확인",
          "localstorage/sessionstorage 학습",
        ],
      },
      {
        title: "SpringBoot 학습하기",
        contents: ["Spring Security 구현", "Spring MVC 패턴 익히기"],
      },
      {
        title: "JWT 인증 처리",
        contents: ["JWT 개념 익히기"],
      },
    ]);
  }, []);

  /**
   * 다음은 TodoList 입력용 이벤트 함수
   */
  const createTitleOnchange = (e) => {
    const { name, value } = e.target;
    setCreateInputTitle({
      ...createInputTitle,
      [name]: value,
    });
  };
  /**
   * 입력시 Todolist 추가하는 기능
   */
  const createTitleButton = () => {
    let to = [];
    to.push(...todoList);
    to.push({
      title: createInputTitle?.title,
      contents: [],
    });
    setTodoList(to);
  };

  // 수정용 메서드
  const updateTitlOnChange = (e, index) => {
    const { name, value } = e.target;
    setChangeTitle({ [index]: { [name]: value } });
    console.log(changeTitle);
  };

  // 수정 부분 입력 후 갱신 메서드
  const updateTitle = (index) => {
    setTodoList(
      update(todoList, {
        [index]: {
          title: { $set: changeTitle[index].title },
        },
      })
    );
  };

  // 삭제 관련 메소드 (제목)
  const removeTitle = (index) => {
    setTodoList(
      update(todoList, {
        $splice: [[index, 1]],
      })
    );
  };

  return (
    <div className="my-2 background-container">
      <Card className="my-2 container">
        <CardHeader className="header-container">
          To-do list 반응형 웹 개발
        </CardHeader>
        <CardBody>
          <CardTitle tag="h2">To-do list</CardTitle>
          <div className="todo">
            {
              // 다음은 각각 데이터를 불려올 때 map을 주로 사용합니다.
              // todoList에 저장된 state 값을
              // 유사 forEach문처럼 todo를 이용하여 출력하고,
              // 상위 div에 key값을 설정하기 위해 index 값을 집어 넣어야 합니다.
              todoList?.map((todo, index) => (
                <div key={index} className="todoContainer">
                  <div className="todoTitle">
                    {isTitleUpdate ? (
                      <div>
                        <Input
                          name="title"
                          defaultValue={todo?.title}
                          onChange={(e) => updateTitlOnChange(e, index)}
                        />
                        <Button onClick={() => updateTitle(index)}>
                          todolist수정
                        </Button>
                        <Button
                          onClick={() => setIsTitleUpdate(!isTitleUpdate)}
                        >
                          취소
                        </Button>
                      </div>
                    ) : (
                      <div>
                        {todo?.title}
                        <Button
                          onClick={() => setIsTitleUpdate(!isTitleUpdate)}
                        >
                          수정
                        </Button>{" "}
                        <PlusCircle />
                        <Button onClick={() => removeTitle(index)}>
                          <Trash3 />
                        </Button>
                      </div>
                    )}
                  </div>

                  {todo?.contents?.map((tc, tcIndex) => (
                    <div key={tcIndex} className="todoContents">
                      - {tc} <Trash3 />
                    </div>
                  ))}
                </div>
              ))
            }
          </div>

          {/**
           *
           */}
          <Form className="addGroup">
            <Input
              className="addInput"
              name="title"
              defaultValue={createInputTitle}
              onChange={createTitleOnchange}
            />
            <Button className="addButton" onClick={createTitleButton}>
              추가
            </Button>
          </Form>
        </CardBody>
      </Card>
    </div>
  );
}

export default App;

 

 

다음 시간에는 Redux 적용 및 LocalStorage에 저장하는 방법에 대해 다뤄보겠습니다.

(7) Todo List 리덕스(Redux) Local Storage 리팩토링하기

https://berkley.tistory.com/11

 

(7) Todo List Redux - Local Storage로 state 리팩토링

지금까지 CRUD 전체를 다루는 연습을 하였습니다. 이번 시간에는 Redux 설치 및 적용, Local Storage를 다루는 시간으로 활용 하겠습니다. 지금까지 따라오신 후 이 글을 확인하시기 바랍니다. (6) Todo Li

berkley.tistory.com

 

 

 

 

 

 

 

 

 

728x90
반응형
LIST