5. 게시글 삭제

윤지영·2024년 3월 25일

🌞 MongoDB 데이터 삭제하기

await db.collection('콜렉션이름').deleteOne(
	{게시물정보}   
);

삭제 기능 구현하기

- ListPage

  • ListItem 클라이언트 컴포넌트로 분리
  • ListItem 컴포넌트에 postData prop으로 전달
    * id는 string형태로 전달해주자!
//  src/app/list/page.js

import styles from "./list.module.css";
import { connectToDatabase } from "@/utils/database";
import ListItem from "./_components/ListItem";
import Link from "next/link";
import TextButton from "@/components/UI/TextButton";

export default async function ListPage() {
  const { postCollection } = await connectToDatabase();
  let postData = await postCollection.find().toArray();
  return (
    <>
      <Link href="/write">
        <TextButton text="게시글 작성" />
      </Link>
      <ul className={styles["list-bg"]}>
        {postData.map((item, index) => (
          <ListItem title={item.title} id={item._id.toString()} />
        ))}
      </ul>
    </>
  );
}

- ListItem 컴포넌트

  • 코드의 일관성 유지, 재사용성을 위해 공통 컴포넌트를 만들어주었다.

    • Message 컴포넌트 : text, type 두 가지 prop을 받습는다. text prop은 화면에 표시될 메시지 내용을, type prop은 메시지의 스타일 유형을 결정하도록 하였다.
    • IconButton은 icon, onclickFn, text(선택적) 세 가지 prop을 받을 수 있도록 하였다.
  • handleDeleteBtnClick()함수는 비동기적으로 서버에 삭제 요청을 보내고, 응답에 따라 성공 또는 오류 메시지를 나타내도록 하였다. 삭제 요청 성공 시, 목록 페이지로 리디렉션하고, 일정 시간 후 메시지가 사라지도록 하였다.

  • 삭제 요청 시 body: JSON.stringify({ _id: id })통해 id를 서버로 전송해줘야 한다!

//src/app/list/_components/ListItem.js

"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { TiEdit } from "react-icons/ti";
import { MdOutlineDeleteSweep } from "react-icons/md";
import IconButton from "@/components/UI/IconButton";

import styles from "./ListItem.module.css";
import { useState } from "react";
import Message from "@/components/UI/Message";

export default function ListItem({ title, id }) {
  const [message, setMessage] = useState("");
  const [messageType, setMessageType] = useState("");
  const router = useRouter();

  const handleDeleteBtnClick = async (e) => {
    console.log(id);
    try {
      const response = await fetch("/api/delete", {
        method: "DELETE",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ _id: id }),
      });
      if (!response.ok) {
        throw new Error("네트워크 응답이 올바르지 않습니다.");
      }
      router.push(`/list`);
      router.refresh();
      setMessageType("success");
      setMessage("게시물이 삭제되었습니다.");
      setTimeout(() => {
        setMessage("");
      }, 3000);
    } catch (error) {
      console.error(error);
      setMessageType("error");
      setMessage(error.message);
    }
  };

  return (
    <>
      {message.length > 0 && <Message text={message} type={messageType} />}
      <li className={`${styles["list-item"]} flex`}>
        <div className={styles["text-box"]}>
          <Link href={`/detail/${id}`}>
            <h4>{title}</h4>
            <p>11</p>
          </Link>
        </div>
        <div className={`flex ${styles["icon-wrap"]}`}>
          <Link href={`/edit/${id}`}>
            <IconButton icon={<TiEdit />} />
          </Link>

          <IconButton
            icon={<MdOutlineDeleteSweep />}
            onclickFn={handleDeleteBtnClick}
          />
        </div>
      </li>
    </>
  );
}

- 게시물 삭제 API

  • deleteOne() 메서드 통해 게시물 삭제
// /app/api/delete/route.js
import { connectToDatabase } from "@/utils/database";
import { ObjectId } from "mongodb";
import { NextResponse } from "next/server";

export async function DELETE(req) {
  try {
    const { _id } = await req.json();
    const { postCollection } = await connectToDatabase();
    const result = await postCollection.deleteOne({ _id: new ObjectId(_id) });
    console.log(result);

    return NextResponse.json({
      message: "게시글이 성공적으로 삭제되었습니다.",
    });
  } catch (error) {
    console.error(error);
    return NextResponse.json(
      { error: "서버 오류가 발생했습니다." },
      { status: 500 }
    );
  }
}

추가작업

app폴더에 loading.js, error.js, not-found.js파일 생성

:: 진행상황 & TODO ::

  • 몽고 DB setting
  • MongoDB 입출력
  • 글 목록 조회 기능(/list)
    • 글 제목,~~
    • 날짜 데이터바인딩
  • 글 상세 페이지(/detail/[id]/page.js)
    • 제목, 내용,
    • 게시 날짜, 댓글 데이터바인딩
  • 글 작성 페이지
  • 글 수정 페이지
  • 글 삭제 페이지
  • 404페이지 만들기
  • error 페이지 만들기
  • loading 페이지 만들기
  • S3 파일업로드
  • Next-auth 회원인증기능
  • 글 작성 페이지 마크다운 작성페이지로 변경
  • 캐싱, 에러처리 등 부가기능
  • 스타일링
  • AWS 클라우드 배포
profile
쑥쑥쑥쑥 레벨업🌱🌼🌳

0개의 댓글