Skip to content

Commit 2c02ac1

Browse files
committed
feat: post edit 기능 tanstack query로 변경
1 parent 43fd795 commit 2c02ac1

File tree

3 files changed

+66
-46
lines changed

3 files changed

+66
-46
lines changed
Binary file not shown.

apps/next-client/src/app/community/[id]/edit/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import React, { useMemo } from 'react';
44
import dynamic from 'next/dynamic';
55
import { useSession } from 'next-auth/react';
6-
import { usePost } from '@/hooks/queries/usePostEdit';
6+
import { usePostEdit } from '@/hooks/queries/usePostEdit';
77
import '@/styles/pages/community/community.scss';
88
import 'react-quill/dist/quill.snow.css';
99
import type Quill from 'quill';
@@ -21,7 +21,7 @@ export default function EditPostPage({ params }: { params: { id: string } }) {
2121
const userId = session?.user?.id;
2222
const accessToken = session?.user?.accessToken || '';
2323

24-
const { title, setTitle, content, setContent, loading, handleUpdatePost, handleDeletePost } = usePost(id, userId, accessToken);
24+
const { title, setTitle, content, setContent, loading, handleUpdatePost, handleDeletePost } = usePostEdit(id, userId, accessToken);
2525

2626
function handleImageUpload(this: { quill: Quill }) {
2727
const editor = this.quill;

apps/next-client/src/hooks/queries/usePostEdit.ts

Lines changed: 64 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,104 @@
1-
import { useEffect, useState } from 'react';
1+
import { useState, useEffect } from 'react';
22
import { useRouter } from 'next/navigation';
3-
import { useQueryClient } from '@tanstack/react-query';
3+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
44
import { axiosInstance } from '@/services/common/axiosInstance';
55
import { API_URLS } from '@/constants/urls';
66
import { ALERT_MESSAGES } from '@/constants/alertMessage';
77

8-
export const usePost = (id: string, userId: string | undefined, accessToken: string) => {
8+
export const usePostEdit = (id: string, userId: string | undefined, accessToken: string) => {
99
const [title, setTitle] = useState('');
1010
const [content, setContent] = useState('');
11-
const [loading, setLoading] = useState(true);
1211
const router = useRouter();
1312
const queryClient = useQueryClient();
1413

15-
useEffect(() => {
16-
// 게시글 가져오기 함수
17-
const fetchPost = async () => {
18-
try {
19-
const response = await axiosInstance.get(`${API_URLS.POSTS}/${id}`);
20-
const post = response.data;
21-
22-
if (post.userId !== userId) {
23-
alert(ALERT_MESSAGES.ERROR.POST.POST_PERMISSION_DENIED);
24-
router.push('/community');
25-
return;
26-
}
14+
// 게시글 조회
15+
const { isLoading: loading, error, data } = useQuery({
16+
queryKey: ['post-edit', id],
17+
queryFn: async () => {
18+
const response = await axiosInstance.get(`${API_URLS.POSTS}/${id}`);
19+
const post = response.data;
2720

28-
setTitle(post.title);
29-
setContent(post.content);
30-
} catch (error) {
31-
console.error('Error fetching post:', error);
32-
alert(ALERT_MESSAGES.ERROR.POST.POST_FETCH_ERROR);
21+
if (post.userId !== userId) {
22+
alert(ALERT_MESSAGES.ERROR.POST.POST_PERMISSION_DENIED);
3323
router.push('/community');
34-
} finally {
35-
setLoading(false);
24+
throw new Error('Permission denied');
3625
}
37-
};
26+
27+
return post;
28+
},
29+
enabled: !!id && !!userId,
30+
staleTime: 5 * 60 * 1000,
31+
gcTime: 10 * 60 * 1000,
32+
});
3833

39-
fetchPost();
40-
}, [id, userId, router]);
34+
useEffect(() => {
35+
if (data) {
36+
setTitle(data.title);
37+
setContent(data.content);
38+
}
39+
}, [data]);
4140

42-
// 게시글 업데이트 함수
43-
const handleUpdatePost = async () => {
44-
try {
41+
useEffect(() => {
42+
if (error) {
43+
console.error('Error fetching post:', error);
44+
alert(ALERT_MESSAGES.ERROR.POST.POST_FETCH_ERROR);
45+
router.push('/community');
46+
}
47+
}, [error, router]);
48+
49+
// 게시글 업데이트
50+
const updatePostMutation = useMutation({
51+
mutationFn: async () => {
4552
if (!title.trim() || !content.trim()) {
4653
alert(ALERT_MESSAGES.ERROR.POST.POST_EMPTY_FIELDS);
47-
return;
54+
throw new Error('Empty fields');
4855
}
4956

50-
await axiosInstance.put(
57+
return axiosInstance.put(
5158
`${API_URLS.POSTS}/${id}`,
5259
{ title, content },
5360
{ headers: { Authorization: `Bearer ${accessToken}` } }
5461
);
55-
62+
},
63+
onSuccess: () => {
5664
alert(ALERT_MESSAGES.SUCCESS.POST.POST_UPDATE);
57-
5865
queryClient.invalidateQueries({ queryKey: ['post', id] });
59-
6066
router.push(`/community/${id}`);
61-
} catch (error) {
67+
},
68+
onError: (error) => {
6269
console.error('Error updating post:', error);
6370
alert(ALERT_MESSAGES.ERROR.POST.POST_UPDATE_ERROR);
6471
}
65-
};
72+
});
6673

67-
// 게시글 삭제 함수
68-
const handleDeletePost = async () => {
69-
try {
70-
if (!window.confirm(ALERT_MESSAGES.CONFIRM.CHECK_DELETE)) return;
74+
// 게시글 삭제
75+
const deletePostMutation = useMutation({
76+
mutationFn: async () => {
77+
if (!window.confirm(ALERT_MESSAGES.CONFIRM.CHECK_DELETE)) {
78+
throw new Error('Delete cancelled');
79+
}
7180

72-
await axiosInstance.delete(`${API_URLS.POSTS}/${id}`, {
73-
headers: { Authorization: `Bearer ${accessToken}` },
81+
return axiosInstance.delete(`${API_URLS.POSTS}/${id}`, {
82+
headers: { Authorization: `Bearer ${accessToken}` }
7483
});
75-
84+
},
85+
onSuccess: () => {
7686
alert(ALERT_MESSAGES.SUCCESS.POST.POST_DELETE);
87+
queryClient.invalidateQueries({ queryKey: ['posts'] });
7788
router.push('/community');
78-
} catch (error) {
89+
},
90+
onError: (error) => {
7991
console.error('Error deleting post:', error);
8092
alert(ALERT_MESSAGES.ERROR.POST.POST_DELETE_ERROR);
8193
}
94+
});
95+
96+
const handleUpdatePost = () => {
97+
updatePostMutation.mutate();
98+
};
99+
100+
const handleDeletePost = () => {
101+
deletePostMutation.mutate();
82102
};
83103

84104
return { title, setTitle, content, setContent, loading, handleUpdatePost, handleDeletePost };

0 commit comments

Comments
 (0)