Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: #173 React Query의 Query Key 정리 #174

Merged
merged 2 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/hooks/query/useProjectQuery.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useQuery } from '@tanstack/react-query';
import { generateProjectsQueryKey, generateProjectUsersQueryKey } from '@utils/queryKeyGenergator';
import { getProjectList, getProjectUserRoleList } from '@services/projectService';

import type { Team } from '@/types/TeamType';
Expand All @@ -13,7 +14,7 @@ export function useReadProjects(teamId: Team['teamId']) {
isError: isProjectError,
error: projectError,
} = useQuery({
queryKey: ['teams', teamId, 'projects'],
queryKey: generateProjectsQueryKey(teamId),
queryFn: async () => {
const { data } = await getProjectList(teamId);
return data;
Expand All @@ -31,7 +32,7 @@ export function useReadProjectUserRoleList(projectId: Project['projectId']) {
isError: isErrorProjectUserRole,
error: projectUserRoleError,
} = useQuery({
queryKey: ['projects', projectId, 'users'],
queryKey: generateProjectUsersQueryKey(projectId),
queryFn: async () => {
const { data } = await getProjectUserRoleList(projectId);
return data;
Expand Down
21 changes: 11 additions & 10 deletions src/hooks/query/useStatusQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import useToast from '@hooks/useToast';
import { PROJECT_STATUS_COLORS } from '@constants/projectStatus';
import { createStatus, getStatusList, updateStatus, updateStatusesOrder } from '@services/statusService';
import { generateProjectQueryKey, generateStatusesQueryKey, generateTasksQueryKey } from '@utils/queryKeyGenergator';

import type { Project } from '@/types/ProjectType';
import type { TaskListWithStatus } from '@/types/TaskType';
Expand Down Expand Up @@ -58,7 +59,7 @@ export function useReadStatuses(projectId: Project['projectId'], statusId?: Proj
isError: isStatusError,
error: statusError,
} = useQuery({
queryKey: ['projects', projectId, 'statuses'],
queryKey: generateStatusesQueryKey(projectId),
queryFn: async () => {
const { data } = await getStatusList(projectId);
return data;
Expand Down Expand Up @@ -103,7 +104,7 @@ export function useCreateStatus(projectId: Project['projectId']) {
onSuccess: () => {
toastSuccess('프로젝트 상태를 추가하였습니다.');
queryClient.invalidateQueries({
queryKey: ['projects', projectId],
queryKey: generateProjectQueryKey(projectId),
});
},
});
Expand All @@ -120,7 +121,7 @@ export function useUpdateStatus(projectId: Project['projectId'], statusId: Proje
onSuccess: () => {
toastSuccess('프로젝트 상태를 수정했습니다.');
queryClient.invalidateQueries({
queryKey: ['projects', projectId],
queryKey: generateProjectQueryKey(projectId),
});
},
});
Expand All @@ -131,28 +132,28 @@ export function useUpdateStatus(projectId: Project['projectId'], statusId: Proje
export function useUpdateStatusesOrder(projectId: Project['projectId']) {
const { toastError } = useToast();
const queryClient = useQueryClient();
const queryKeyTasks = ['projects', projectId, 'tasks'];
const queryKeyStatuses = ['projects', projectId, 'statuses'];
const TasksQueryKey = generateTasksQueryKey(projectId);
const statusesQueryKey = generateStatusesQueryKey(projectId);

const mutation = useMutation({
mutationFn: (newStatusTaskList: TaskListWithStatus[]) => {
const statusOrders: StatusOrder[] = newStatusTaskList.map(({ statusId, sortOrder }) => ({ statusId, sortOrder }));
return updateStatusesOrder(projectId, { statuses: statusOrders });
},
onMutate: async (newStatusTaskList: TaskListWithStatus[]) => {
await queryClient.cancelQueries({ queryKey: queryKeyTasks });
await queryClient.cancelQueries({ queryKey: TasksQueryKey });

const previousStatusTaskList = queryClient.getQueryData(queryKeyTasks);
queryClient.setQueryData(queryKeyTasks, newStatusTaskList);
const previousStatusTaskList = queryClient.getQueryData(TasksQueryKey);
queryClient.setQueryData(TasksQueryKey, newStatusTaskList);

return { previousStatusTaskList };
},
onError: (error, newStatusTaskList, context) => {
toastError('프로젝트 상태 순서 변경에 실패 하였습니다. 잠시후 다시 진행해주세요.');
queryClient.setQueryData(queryKeyTasks, context?.previousStatusTaskList);
queryClient.setQueryData(TasksQueryKey, context?.previousStatusTaskList);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: queryKeyStatuses, type: 'all' });
queryClient.invalidateQueries({ queryKey: statusesQueryKey, type: 'all' });
},
});

Expand Down
37 changes: 21 additions & 16 deletions src/hooks/query/useTaskQuery.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { useMemo } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
generateTaskAssigneesQueryKey,
generateTaskFilesQueryKey,
generateTasksQueryKey,
} from '@utils/queryKeyGenergator';
import {
addAssignee,
createTask,
Expand Down Expand Up @@ -38,7 +43,7 @@ function getTaskNameList(taskList: TaskListWithStatus[], excludedTaskName?: Task
export function useCreateStatusTask(projectId: Project['projectId']) {
const { toastError, toastSuccess } = useToast();
const queryClient = useQueryClient();
const queryKey = ['projects', projectId, 'tasks'];
const tasksQueryKey = generateTasksQueryKey(projectId);

const mutation = useMutation({
mutationFn: (formData: TaskCreationForm) => createTask(projectId, formData),
Expand All @@ -47,7 +52,7 @@ export function useCreateStatusTask(projectId: Project['projectId']) {
},
onSuccess: () => {
toastSuccess('프로젝트 일정을 등록하였습니다.');
queryClient.invalidateQueries({ queryKey });
queryClient.invalidateQueries({ queryKey: tasksQueryKey });
},
});

Expand Down Expand Up @@ -76,7 +81,7 @@ export function useReadStatusTasks(projectId: Project['projectId'], taskId?: Tas
isError: isTaskError,
error: taskError,
} = useQuery({
queryKey: ['projects', projectId, 'tasks'],
queryKey: generateTasksQueryKey(projectId),
queryFn: async () => {
const { data } = await findTaskList(projectId);
return data;
Expand All @@ -100,7 +105,7 @@ export function useReadStatusTasks(projectId: Project['projectId'], taskId?: Tas
export function useUpdateTasksOrder(projectId: Project['projectId']) {
const { toastError } = useToast();
const queryClient = useQueryClient();
const queryKey = ['projects', projectId, 'tasks'];
const tasksQueryKey = generateTasksQueryKey(projectId);

const mutation = useMutation({
mutationFn: (newStatusTaskList: TaskListWithStatus[]) => {
Expand All @@ -113,16 +118,16 @@ export function useUpdateTasksOrder(projectId: Project['projectId']) {
return updateTaskOrder(projectId, { tasks: taskOrders });
},
onMutate: async (newStatusTaskList: TaskListWithStatus[]) => {
await queryClient.cancelQueries({ queryKey });
await queryClient.cancelQueries({ queryKey: tasksQueryKey });

const previousStatusTaskList = queryClient.getQueryData(queryKey);
queryClient.setQueryData(queryKey, newStatusTaskList);
const previousStatusTaskList = queryClient.getQueryData(tasksQueryKey);
queryClient.setQueryData(tasksQueryKey, newStatusTaskList);

return { previousStatusTaskList };
},
onError: (err, newStatusTaskList, context) => {
toastError('일정 순서 변경에 실패 하였습니다. 잠시후 다시 진행해주세요.');
queryClient.setQueryData(queryKey, context?.previousStatusTaskList);
queryClient.setQueryData(tasksQueryKey, context?.previousStatusTaskList);
},
});

Expand All @@ -137,7 +142,7 @@ export function useReadAssignees(projectId: Project['projectId'], taskId: Task['
error: assigneeError,
isError: isAssigneeError,
} = useQuery({
queryKey: ['projects', projectId, 'tasks', taskId, 'assignees'],
queryKey: generateTaskAssigneesQueryKey(projectId, taskId),
queryFn: async () => {
const { data } = await findAssignees(projectId, taskId);
return data;
Expand All @@ -155,7 +160,7 @@ export function useReadTaskFiles(projectId: Project['projectId'], taskId: Task['
error: taskFileError,
isError: isTaskFileError,
} = useQuery({
queryKey: ['projects', projectId, 'tasks', taskId, 'files'],
queryKey: generateTaskFilesQueryKey(projectId, taskId),
queryFn: async () => {
const { data } = await findTaskFiles(projectId, taskId);
return data;
Expand All @@ -168,14 +173,14 @@ export function useReadTaskFiles(projectId: Project['projectId'], taskId: Task['
export function useUpdateTaskInfo(projectId: Project['projectId'], taskId: Task['taskId']) {
const { toastError, toastSuccess } = useToast();
const queryClient = useQueryClient();
const queryKey = ['projects', projectId, 'tasks'];
const tasksQueryKey = generateTasksQueryKey(projectId);

const mutation = useMutation({
mutationFn: (formData: TaskUpdateForm) => updateTaskInfo(projectId, taskId, formData),
onError: () => toastError('일정 정보 수정에 실패 했습니다. 잠시후 다시 시도해주세요.'),
onSuccess: () => {
toastSuccess('일정 정보를 수정 했습니다.');
queryClient.invalidateQueries({ queryKey });
queryClient.invalidateQueries({ queryKey: tasksQueryKey });
},
});

Expand All @@ -186,7 +191,7 @@ export function useUpdateTaskInfo(projectId: Project['projectId'], taskId: Task[
export function useAddAssignee(projectId: Project['projectId'], taskId: Task['taskId']) {
const { toastError, toastSuccess } = useToast();
const queryClient = useQueryClient();
const queryKey = ['projects', projectId, 'tasks', taskId, 'assignees'];
const taskAssigneesQueryKey = generateTaskAssigneesQueryKey(projectId, taskId);

const mutation = useMutation({
mutationFn: (userId: User['userId']) => addAssignee(projectId, taskId, userId),
Expand All @@ -195,7 +200,7 @@ export function useAddAssignee(projectId: Project['projectId'], taskId: Task['ta
},
onSuccess: () => {
toastSuccess('수행자를 추가 하였습니다.');
queryClient.invalidateQueries({ queryKey });
queryClient.invalidateQueries({ queryKey: taskAssigneesQueryKey });
},
});

Expand All @@ -206,7 +211,7 @@ export function useAddAssignee(projectId: Project['projectId'], taskId: Task['ta
export function useDeleteAssignee(projectId: Project['projectId'], taskId: Task['taskId']) {
const { toastError, toastSuccess } = useToast();
const queryClient = useQueryClient();
const queryKey = ['projects', projectId, 'tasks', taskId, 'assignees'];
const taskAssigneesQueryKey = generateTaskAssigneesQueryKey(projectId, taskId);

const mutation = useMutation({
mutationFn: (userId: User['userId']) => deleteAssignee(projectId, taskId, userId),
Expand All @@ -215,7 +220,7 @@ export function useDeleteAssignee(projectId: Project['projectId'], taskId: Task[
},
onSuccess: () => {
toastSuccess('수행자를 삭제 하였습니다.');
queryClient.invalidateQueries({ queryKey });
queryClient.invalidateQueries({ queryKey: taskAssigneesQueryKey });
},
});

Expand Down
39 changes: 20 additions & 19 deletions src/hooks/query/useTeamQuery.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { generateTeamsQueryKey } from '@utils/queryKeyGenergator';
import { getTeamList } from '@services/userService';
import { acceptTeamInvitation, declineTeamInvitation, deleteTeam, leaveTeam } from '@services/teamService';
import useToast from '@hooks/useToast';
import type { TeamListWithApproval } from '@/types/TeamType';
import useToast from '@/hooks/useToast';

export function useReadTeams() {
const {
Expand All @@ -11,7 +12,7 @@ export function useReadTeams() {
isError,
error,
} = useQuery<TeamListWithApproval[], Error>({
queryKey: ['teams'],
queryKey: generateTeamsQueryKey(),
queryFn: async () => {
const { data } = await getTeamList();
return data;
Expand All @@ -27,12 +28,13 @@ export function useReadTeams() {
export function useLeaveTeam() {
const queryClient = useQueryClient();
const { toastSuccess, toastError } = useToast();
const teamsQueryKey = generateTeamsQueryKey();

return useMutation({
mutationFn: (teamId: number) => leaveTeam(teamId),
onSuccess: () => {
toastSuccess('팀에서 탈퇴했습니다.');
queryClient.invalidateQueries({ queryKey: ['teams'] });
queryClient.invalidateQueries({ queryKey: teamsQueryKey });
},
onError: () => {
toastError('탈퇴에 실패했습니다. 다시 시도해 주세요.');
Expand All @@ -43,51 +45,50 @@ export function useLeaveTeam() {
export function useDeleteTeam() {
const queryClient = useQueryClient();
const { toastSuccess, toastError } = useToast();
const teamsQueryKey = generateTeamsQueryKey();

return useMutation({
mutationFn: async (teamId: number) => {
const response = await deleteTeam(teamId);

return response;
mutationFn: (teamId: number) => deleteTeam(teamId),
onError: () => {
toastError('팀 삭제를 실패했습니다. 다시 시도해 주세요.');
},
onSuccess: () => {
toastSuccess('팀을 삭제하였습니다.');
queryClient.invalidateQueries({ queryKey: ['teams'] });
},
onError: () => {
toastError('팀 삭제를 실패했습니다. 다시 시도해 주세요.');
queryClient.invalidateQueries({ queryKey: teamsQueryKey });
},
});
}

export function useApproveTeamInvitation() {
const queryClient = useQueryClient();
const { toastSuccess, toastError } = useToast();
const teamsQueryKey = generateTeamsQueryKey();

return useMutation({
mutationFn: (teamId: number) => acceptTeamInvitation(teamId),
onSuccess: () => {
toastSuccess('초대를 수락했습니다.');
queryClient.invalidateQueries({ queryKey: ['teams'] });
},
onError: () => {
toastError('초대 수락에 실패했습니다. 다시 시도해 주세요.');
},
onSuccess: () => {
toastSuccess('초대를 수락했습니다.');
queryClient.invalidateQueries({ queryKey: teamsQueryKey });
},
});
}

export function useRejectTeamInvitation() {
const queryClient = useQueryClient();
const { toastSuccess, toastError } = useToast();
const teamsQueryKey = generateTeamsQueryKey();

return useMutation({
mutationFn: (teamId: number) => declineTeamInvitation(teamId),
onSuccess: () => {
toastSuccess('초대를 거절했습니다.');
queryClient.invalidateQueries({ queryKey: ['teams'] });
},
onError: () => {
toastError('초대 거절에 실패했습니다. 다시 시도해 주세요.');
},
onSuccess: () => {
toastSuccess('초대를 거절했습니다.');
queryClient.invalidateQueries({ queryKey: teamsQueryKey });
},
});
}
Loading