더북(TheBook)

이제 게시글 화면에서 삭제 버튼을 눌러보세요. 다음과 같이 방금 만든 AskDialog가 나타났나요?

▲ 그림 15-15 AskDialog

삭제 기능을 구현할 준비가 거의 끝났습니다. 삭제를 위한 API를 작성해주세요.

api/articles.ts - deleteArticle

export async function deleteArticle(id: number) {
  await client.delete<Article>(`/articles/${id}`);
  return null; // 응답 결과가 없기 때문에 null 반환
}

이 API를 useMutation을 거쳐서 호출하면 됩니다. 게시글 삭제 이후에는 navigation.goBack하여 이전 화면으로 이동하고, queryClient를 사용하여 게시글 목록을 갱신합니다. 갱신 로직은 이전에 게시글을 삭제했을 때 작성한 로직과 유사하게 findmap을 사용하고, 추가로 filter 함수도 활용하겠습니다. 로직 작성이 번거롭다면 그냥 invalidate를 해도 무방합니다.

components/ArticleActionButtons.tsx

(...)
import {InfiniteData, useMutation, useQueryClient} from 'react-query';
import {deleteArticle} from '../api/articles';
import {Article} from '../api/types';

export interface ArticleActionButtonsProps {
  articleId: number;
}

function ArticleActionButtons({articleId}: ArticleActionButtonsProps) {
  const [askRemove, setAskRemove] = useState(false);
  const navigation = useNavigation<RootStackNavigationProp>();
  const queryClient = useQueryClient();

  const {mutate} = useMutation(deleteArticle, {
    onSuccess: () => {
      navigation.goBack();
      queryClient.setQueryData<InfiniteData<Article[]>>('articles', (data) => {
        if (!data) {
          return {pageParams: [], pages: []};
        }

        return {
          pageParams: data!.pageParams,
          pages: data!.pages.map((page) =>
            page.find((a) => a.id === articleId) // 우리가 수정할 항목이 있는 페이지를 찾고
              ? page.filter((a) => a.id !== articleId) // articleId와 일치하는 것은 제외
              : page,
          ),
        };
      });
    },
  });

  (...)

  const onConfirmRemove = () => {
    setAskRemove(false);
    mutate(articleId);
  };

  (...)

삭제 기능 구현이 끝났습니다! 잘 삭제되는지 확인해보세요.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.