useQuery 에서 더이상 onError 콜백을 사용할 수 없습니다.
React Query 에서 자주 쓰였었던 onError,onSettled,onSuccess 세개의 콜백이 더이상 사용할수 없게되었습니다.
그래서 저같은경우 API를 정의한 파일에서 에러발생시 토스트 알림을 띄우도록 설정을 해주었습니다.
export async function getChatHistory(
roomId: string,
targetId: number,
): Promise<ChatHistory> {
try{
let url = `/endpoint/api/chatroom/${roomId}/message?size=20`;
if (targetId !== 0) {
url += `&targetId=${targetId}`;
}
const response = await fetch(url);
if (response.status === 401) {
throw new AuthError('로그인이 필요합니다.');
}
if (response.status === 400) {
throw new Error('현재 참여하고 있지 않은 채팅룸입니다.');
}
if(!response.ok){
throw new Error("잠시후 다시 시도해주세요.")
}
return await response.json();
}catch(error){
if(error instanceof Error)Toast.error(error.message)
if(error instanceof AuthError){
Toast.error(error.message)
window.location.assign('/auth/login')
}
throw error
}
}
하지만 위와 같이한다면 문제점은 무엇일까요?
맞습니다. 바로 모든 useQuery 훅의 fetcher API들은 에러처리에 똑같은코드를 여러번 작성해주어야 합니다. 또한 API 요청이 수십 수백개라면 반복되어지는 코드가 상당히 많아지게 될것입니다.
또한 API 호출 코드들을 모아둔곳에서 토스트 알람 호출을 한다는것이 썩 마음에 들진 않습니다.
한곳에서 공통으로 처리하자.
// ..ReactQueryProvider.tsx
'use client';
import { AuthError } from '@/lib/error';
import Toast from '@/utils/notification';
import {
MutationCache,
QueryCache,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query';
// 에러핸들링 함수 만약 에러클래스를 여러개 정의한다면 에러별로 공통된 에러핸들링을 정의할 수 있음.
const handleError = (error: unknown) => {
if (error instanceof Error) Toast.error(error.message);
if (error instanceof AuthError) {
Toast.error(error.message);
window.location.assign(`/auth/login`);
}
};
// useMutation 과 useQuery 훅의 에러를 한곳에서 공통적으로 처리할수 있도록 하였습니다.
const queryClient = new QueryClient({
mutationCache: new MutationCache({
onError: (error) => handleError(error),
}),
// useQuery의 onError callback 이 deprecated(더 이상 사용되지않음) 되었기 때문에 추가하였습니다. useQuery 훅이 작동할때 에러가 발생한다면 에러 토스트알림을 띄웁니다.
queryCache: new QueryCache({
onError: (error) => handleError(error),
}),
});
export default function ReactQueryProvider({
children,
}: {
children: React.ReactNode;
}) {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
}
React Query 를 우리 프로젝트에서 사용할수있도록 해주는 Provider 파일입니다.
handleError 함수를 통해 각 에러마다 에러처리를 수행할수있도록 해줍니다.
queryCache 를 통해 useQuery 훅에 대한 공통 에러처리를 수행할 수 있습니다.
mutationCache 를 통해 useMutation 훅에 대한 공통 에러처리를 수행할 수 있습니다.
queryCache 를 사용하여 useQuery에 대한 콜백에러를 해주었습니다. 해당 콜백은 쿼리당 한 번만 호출되며 useQuery를 호출한 컴포넌트 외부에 존재하기에 클로저 문제도 신경쓸 필요가 없게 되었습니다.
// 채팅룸 이전 채팅기록 조회 API
export async function getChatHistory(
roomId: string,
targetId: number,
): Promise<ChatHistory> {
let url = `/endpoint/api/chatroom/${roomId}/message?size=20`;
if (targetId !== 0) {
url += `&targetId=${targetId}`;
}
const response = await fetch(url);
if (response.status === 401) {
throw new AuthError('로그인이 필요합니다.');
}
if (response.status === 400) {
throw new Error('현재 참여하고 있지 않은 채팅룸입니다.');
}
if (!response.ok) {
throw new Error('잠시후 다시 시도해주세요.');
}
return response.json();
}
더이상 공통적인 에러처리때문에 수많은 try catch 문을 작성할 필요가 없게되었으며, 토스트 알람 호출 함수도 매번 써줄 필요가 없게 되었습니다!
'FrontEnd' 카테고리의 다른 글
Light House를 통한 웹 성능 최적화 진행 해보기 (0) | 2023.11.05 |
---|---|
Next.js 프로젝트 폴더구조 개선 (1) | 2023.11.03 |
리액트 Stompjs,Sockjs 실시간 채팅 구현 - (2) (0) | 2023.10.20 |
리액트 Stompjs,Sockjs 실시간 채팅 구현 - (1) (0) | 2023.10.16 |
프론트엔드 클린코드란?(지극히 주관적) (1) | 2023.10.11 |