221124 TIL axios.delete 요청 시 데이터 전달하기

오늘은 마이 페이지의 게시글 리스트에서 체크한 게시글을 삭제하는 기능을 구현했다.
처음에 작업 설계할 때 이 기능을 어떻게 구현해야 할지 전혀 감이 잡히지 않아 작업 설계하는데 어려움을 겪었다.
우선 delete 요청을 기존에 게시글 삭제할때 사용하던 api요청을 사용할지 새로 만들어서 새로운 api 요청을 사용할지 고민을 했었고 두 번째로 체크박스에 선택한 게시글의 아이디를 어떻게 저장하고 어떻게 지워야 할지 기능 구현에 대한 고민을 했었다.

우선 delete요청 하는 방법으로는 두 가지 방법을 생각했는데 그전에 체크한 게시글의 아이디를 저장하는 방법부터 정리해보자.

첫 번째로 체크한 게시글의 아이디를 저장할 배열을 useState로 만들어준다. 그리고 checkbox 타입인 input에 onChange함수를 이용해 해당 체크박스의 checked상태가 true이면 해당 게시글의 id를 배열에 저장한다.

체크 해제하면 배열에 저장된 아이디 값을 제거하기 위해 filter를 이용해 제거해준다.

const [checkedPosts, setCheckedPosts] = useState([]);

const handleChangeCheck = (checked, postId) => {
    if (checked) {
      setCheckedPosts([...checkedPosts, postId]);
    }

    if (!checked) {
      setCheckedPosts(checkedPosts.filter((checkedPostId) => checkedPostId !== postId));
    }
};

<input
  type="checkbox"
  onChange={(e) => handleChangeCheck(e.target.checked, post.id)}
  checked={checkedPosts.indexOf(post.id) >= 0}
/>


이제 체크한 게시글의 아이디 값은 checkedPosts 배열에 저장이 되어 있는데 이 배열 안의 게시글들을 지우는 방법이 두 가지가 있었다.

1. 게시글의 아이디가 저장되어있는 배열을 axios.delete할때 전달해주고 백엔드에서 배열 안의 게시글 아이디를 하나씩 지우는 방법
2. 프론트엔드에서 게시글의 아이디 배열을 map을 이용해 아이디 하나씩 delete요청을 반복하는 방법

두 가지가 있었는데 백엔드에서 아무것도 만들어 주지 않아도 되는 두 번째 방법으로 진행했었다. (백엔드에서 아무것도 안 해줘도 되는 이유는 기존에 게시글 삭제할 때 만들었던 delete 요청을 재사용할 거였기 때문)

  async deleteCheckedPost(checkedPosts) {
    await checkedPosts.map((postId) => postApiService.deletePost(postId));

    this.publish();
  }


그런데 이 방법에는 문제가 하나 있었다. 게시글을 삭제하면 해당 게시글이 사라진 화면이 바로 반영되게 하기 위해 사용자가 작성한 게시글을 불러오는 함수를 한번 더 호출해서 화면이 업데이트 되게 하려고 했는데 화면이 업데이트가 되지 않았다.

그 이유를 알아보니 게시글의 아이디가 들어있는 배열을 모두 delete하기 전에 사용자가 작성한 게시글을 불러오는 함수가 호출이 돼서 화면이 업데이트되지 않았었다.
해결방법으로 게시글을 불러오는 함수를 두번 호출하면 화면이 업데이트되긴 하는데 똑같은 함수를 두 번 연속으로 호출하는 모양이 이상했고 또 지우려는 게시글이 1000개일 때 delete 요청을 한 번에 1000번 하게 되는데 한 번 호출해도 될 문제를 1000번 호출하는 게 매우 비효율적이라고 생각했다.

그래서 두번째 방법으로 배열 자체를 백엔드에 전달해주는 방법으로 진행했다.
기존 delete 요청하는 메서드는 postId를 백엔드에서 pathvariable로 받아서 사용했었는데 이번에는 배열 데이터를 전달해주는 거라 새로 axios.delete 하는 메서드를 만들어서 body에 배열 데이터를 전달해서 delete 요청을 했는데 required request body is missing 에러가 발생했다.

delete 요청할때 data를 같이 보내준 적이 없어 아래와 같이 axios.post 요청할 때 데이터를 보내주는 방법과 동일하게 진행했었는데 이게 문제였던 것이었다.

axios.delete 요청할 때 데이터를 같이 보내려면 아래와 같이 data: {} 형태로 보내줘야 body에 data가 들어간다.

백엔드에서는 위에서 전달해준 게시글 아이디가 담겨있는 배열 데이터를 dto로 받아서 forEach를 이용해  반복해서 지워주면 된다.

이제 내 정보 페이지에서도 삭제하고 싶은 게시글을 선택하고 삭제 버튼을 누르면 게시글을 삭제할 수 있다.