From 4aa1dee1e9fb2bc3fe051a5fcb471def0e3b1526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=ED=98=84=EC=A1=B0?= Date: Thu, 12 Sep 2024 10:43:00 +0900 Subject: [PATCH] =?UTF-8?q?Refactor:=20hooks=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthHooks.ts | 93 +++++++------------ frontend/src/hooks/useProjectHooks.ts | 114 ++++++++---------------- frontend/src/hooks/useWorkspaceHooks.ts | 96 +++++--------------- 3 files changed, 93 insertions(+), 210 deletions(-) diff --git a/frontend/src/hooks/useAuthHooks.ts b/frontend/src/hooks/useAuthHooks.ts index ff52994..24b3342 100644 --- a/frontend/src/hooks/useAuthHooks.ts +++ b/frontend/src/hooks/useAuthHooks.ts @@ -2,55 +2,25 @@ import { useQuery, UseQueryResult, useMutation, useQueryClient, UseMutationResul import { AxiosError } from 'axios'; import useAuthStore from '@/stores/useAuthStore'; import { reissueTokenApi, fetchProfileApi } from '@/api/authApi'; +import { SuccessResponse, RefreshTokenResponseDTO, MemberResponseDTO, CustomError } from '@/types'; import { useState, useEffect } from 'react'; -interface TokenResponse { - status: number; - code: number; - message: string; - data: { - accessToken: string; - }; - errors: Array<{ - field: string; - code: string; - message: string; - objectName: string; - }>; - isSuccess: boolean; -} - -interface ProfileResponse { - status: number; - code: number; - message: string; - data: { - id: number; - nickname: string; - profileImage: string; - }; - errors: Array<{ - field: string; - code: string; - message: string; - objectName: string; - }>; - isSuccess: boolean; -} - -interface ErrorResponse { - message: string; -} - -export const useReissueToken = (): UseMutationResult> => { +export const useReissueToken = (): UseMutationResult< + SuccessResponse, + AxiosError +> => { const queryClient = useQueryClient(); const { setLoggedIn } = useAuthStore(); return useMutation({ mutationFn: reissueTokenApi, onSuccess: (data) => { - setLoggedIn(true, data.data.accessToken); - queryClient.invalidateQueries({ queryKey: ['profile'] }); + if (data.isSuccess && data.data) { + setLoggedIn(true, data.data.accessToken); + queryClient.invalidateQueries({ queryKey: ['profile'] }); + } else { + console.error('토큰 재발급 응답 오류:', data.message); + } }, onError: (error) => { console.error('토큰 재발급 실패:', error?.response?.data?.message || '알 수 없는 오류'); @@ -58,24 +28,23 @@ export const useReissueToken = (): UseMutationResult> => { +export const useProfile = (): UseQueryResult, AxiosError> => { const { accessToken, setProfile } = useAuthStore(); - return useQuery>({ + const query = useQuery, AxiosError>({ queryKey: ['profile'], queryFn: fetchProfileApi, enabled: !!accessToken, - select: (data) => { - if (data.isSuccess) { - setProfile({ - id: data.data.id, - nickname: data.data.nickname, - profileImage: data.data.profileImage, - }); - } - return data; - }, + select: (data) => data, }); + + useEffect(() => { + if (query.data?.isSuccess) { + setProfile(query.data.data); + } + }, [query.data, setProfile]); + + return query; }; export const useFetchProfile = () => { @@ -83,22 +52,20 @@ export const useFetchProfile = () => { const [isFetched, setIsFetched] = useState(false); useEffect(() => { - if (!profile.id && !isFetched) { + if (!profile && !isFetched) { fetchProfileApi() .then((data) => { - if (data?.isSuccess && data.data) { - setProfile({ - id: data.data.id, - nickname: data.data.nickname, - profileImage: data.data.profileImage, - }); + if (data.isSuccess && data.data) { + setProfile(data.data); setIsFetched(true); + } else { + console.error('프로필 응답 오류:', data.message); } }) - .catch((error) => { + .catch((error: AxiosError) => { alert('프로필을 가져오는 중 오류가 발생했습니다. 다시 시도해주세요.'); - console.error('프로필 가져오기 실패:', error); + console.error('프로필 가져오기 실패:', error?.response?.data?.message || '알 수 없는 오류'); }); } - }, [profile.id, setProfile, isFetched]); + }, [profile, setProfile, isFetched]); }; diff --git a/frontend/src/hooks/useProjectHooks.ts b/frontend/src/hooks/useProjectHooks.ts index a2f8ff8..35f1aef 100644 --- a/frontend/src/hooks/useProjectHooks.ts +++ b/frontend/src/hooks/useProjectHooks.ts @@ -9,80 +9,46 @@ import { addProjectMemberApi, removeProjectMemberApi, } from '@/api/projectApi'; - -interface Project { - id: number; - title: string; - workspaceId: number; - projectType: string; - createdAt: string; - updatedAt: string; -} - -interface ProjectsResponse { - status: number; - code: number; - message: string; - data: { - workspaceResponses: Project[]; - }; - errors: Array<{ - field: string; - code: string; - message: string; - objectName: string; - }>; - isSuccess: boolean; -} - -interface ErrorResponse { - message: string; -} +import { BaseResponse, ProjectResponseDTO, ProjectListResponseDTO, CustomError } from '@/types'; export const useGetProject = ( projectId: number, memberId: number -): UseQueryResult> => { - return useQuery>({ +): UseQueryResult, AxiosError> => { + return useQuery, AxiosError>({ queryKey: ['project', projectId], queryFn: () => getProjectApi(projectId, memberId), }); }; export const useUpdateProject = (): UseMutationResult< - ProjectsResponse, - AxiosError, - { projectId: number; memberId: number; data: { title: string; projectType: string } } + BaseResponse, + AxiosError, + { + projectId: number; + memberId: number; + data: { title: string; projectType: 'classification' | 'detection' | 'segmentation' }; + } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ projectId, memberId, data }) => updateProjectApi(projectId, memberId, data), onSuccess: (data) => { - const project = data.data?.workspaceResponses?.[0]; - if (project) { - queryClient.invalidateQueries({ queryKey: ['project', project.id] }); - } else { - console.error('프로젝트 데이터가 없습니다.'); - } + queryClient.invalidateQueries({ queryKey: ['project', data.data.id] }); }, }); }; export const useDeleteProject = (): UseMutationResult< - ProjectsResponse, - AxiosError, + BaseResponse, + AxiosError, { projectId: number; memberId: number } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ projectId, memberId }) => deleteProjectApi(projectId, memberId), - onSuccess: (data) => { - const project = data.data?.workspaceResponses?.[0]; - if (project) { - queryClient.invalidateQueries({ queryKey: ['project', project.id] }); - } else { - console.error('프로젝트 데이터가 없습니다.'); - } + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['project', variables.projectId] }); }, }); }; @@ -90,61 +56,59 @@ export const useDeleteProject = (): UseMutationResult< export const useGetAllProjects = ( workspaceId: number, memberId: number, - lastProjectId?: number, - limit: number = 10 -): UseQueryResult> => { - return useQuery>({ + options?: { enabled: boolean } +): UseQueryResult, AxiosError> => { + return useQuery, AxiosError>({ queryKey: ['projects', workspaceId], - queryFn: () => getAllProjectsApi(workspaceId, memberId, lastProjectId, limit), + queryFn: () => getAllProjectsApi(workspaceId, memberId), + enabled: options?.enabled, }); }; export const useCreateProject = (): UseMutationResult< - ProjectsResponse, - AxiosError, - { workspaceId: number; memberId: number; data: { title: string; projectType: string } } + BaseResponse, + AxiosError, + { + workspaceId: number; + memberId: number; + data: { title: string; projectType: 'classification' | 'detection' | 'segmentation' }; + } > => { + const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ workspaceId, memberId, data }) => createProjectApi(workspaceId, memberId, data), + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['projects', variables.workspaceId] }); + }, }); }; export const useAddProjectMember = (): UseMutationResult< - ProjectsResponse, - AxiosError, + BaseResponse, + AxiosError, { projectId: number; memberId: number; newMemberId: number; privilegeType: string } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ projectId, memberId, newMemberId, privilegeType }) => addProjectMemberApi(projectId, memberId, newMemberId, privilegeType), - onSuccess: (data) => { - const project = data.data?.workspaceResponses?.[0]; - if (project) { - queryClient.invalidateQueries({ queryKey: ['project', project.id] }); - } else { - console.error('프로젝트 데이터가 없습니다.'); - } + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['project', variables.projectId] }); }, }); }; export const useRemoveProjectMember = (): UseMutationResult< - ProjectsResponse, - AxiosError, + BaseResponse, + AxiosError, { projectId: number; memberId: number; targetMemberId: number } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ projectId, memberId, targetMemberId }) => removeProjectMemberApi(projectId, memberId, targetMemberId), - onSuccess: (data) => { - const project = data.data?.workspaceResponses?.[0]; - if (project) { - queryClient.invalidateQueries({ queryKey: ['project', project.id] }); - } else { - console.error('프로젝트 데이터가 없습니다.'); - } + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['project', variables.projectId] }); }, }); }; diff --git a/frontend/src/hooks/useWorkspaceHooks.ts b/frontend/src/hooks/useWorkspaceHooks.ts index e2f37da..f1dc31a 100644 --- a/frontend/src/hooks/useWorkspaceHooks.ts +++ b/frontend/src/hooks/useWorkspaceHooks.ts @@ -9,90 +9,42 @@ import { addWorkspaceMemberApi, removeWorkspaceMemberApi, } from '@/api/workspaceApi'; - -interface WorkspaceResponse { - status: number; - code: number; - message: string; - data: { - id: number; - memberId: string; - title: string; - content: string; - createdAt: string; - updatedAt: string; - }; - errors: Array<{ - field: string; - code: string; - message: string; - objectName: string; - }>; - isSuccess: boolean; -} -interface Workspace { - id: number; - memberId: string; - title: string; - content: string; - createdAt: string; - updatedAt: string; -} - -interface GetAllWorkspacesResponse { - status: number; - code: number; - message: string; - data: { - workspaceResponses: Workspace[]; - }; - errors: Array<{ - field: string; - code: string; - message: string; - objectName: string; - }>; - isSuccess: boolean; -} - -interface ErrorResponse { - message: string; -} +import { BaseResponse, WorkspaceResponseDTO, WorkspaceListResponseDTO, CustomError } from '@/types'; export const useGetWorkspace = ( workspaceId: number, memberId: number -): UseQueryResult> => { - return useQuery>({ +): UseQueryResult, AxiosError> => { + return useQuery, AxiosError>({ queryKey: ['workspace', workspaceId], queryFn: () => getWorkspaceApi(workspaceId, memberId), }); }; export const useUpdateWorkspace = (): UseMutationResult< - WorkspaceResponse, - AxiosError, + BaseResponse, + AxiosError, { workspaceId: number; memberId: number; data: { title: string; content: string } } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ workspaceId, memberId, data }) => updateWorkspaceApi(workspaceId, memberId, data), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['workspace'] }); + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['workspace', variables.workspaceId] }); }, }); }; export const useDeleteWorkspace = (): UseMutationResult< - WorkspaceResponse, - AxiosError, + BaseResponse, + AxiosError, { workspaceId: number; memberId: number } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ workspaceId, memberId }) => deleteWorkspaceApi(workspaceId, memberId), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['workspace'] }); + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['workspace', variables.workspaceId] }); }, }); }; @@ -101,52 +53,52 @@ export const useGetAllWorkspaces = ( memberId: number, lastWorkspaceId?: number, limit?: number -): UseQueryResult> => { - return useQuery>({ +): UseQueryResult, AxiosError> => { + return useQuery, AxiosError>({ queryKey: ['workspaces'], queryFn: () => getAllWorkspacesApi(memberId, lastWorkspaceId, limit), }); }; export const useCreateWorkspace = (): UseMutationResult< - WorkspaceResponse, - AxiosError, + BaseResponse, + AxiosError, { memberId: number; data: { title: string; content: string } } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ memberId, data }) => createWorkspaceApi(memberId, data), onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['workspace'] }); + queryClient.invalidateQueries({ queryKey: ['workspaces'] }); }, }); }; export const useAddWorkspaceMember = (): UseMutationResult< - WorkspaceResponse, - AxiosError, + BaseResponse, + AxiosError, { workspaceId: number; memberId: number; newMemberId: number } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ workspaceId, memberId, newMemberId }) => addWorkspaceMemberApi(workspaceId, memberId, newMemberId), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['workspace'] }); + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['workspace', variables.workspaceId] }); }, }); }; export const useRemoveWorkspaceMember = (): UseMutationResult< - WorkspaceResponse, - AxiosError, + BaseResponse, + AxiosError, { workspaceId: number; memberId: number; targetMemberId: number } > => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ workspaceId, memberId, targetMemberId }) => removeWorkspaceMemberApi(workspaceId, memberId, targetMemberId), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['workspace'] }); + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ queryKey: ['workspace', variables.workspaceId] }); }, }); };