react-query의 success, error, loading과 핸들링
현재 하고있는 프로젝트는 간단한 SPA 커뮤니티의 구현이며
next.js 프로젝트 생성은 create-next-app을 이용하였고
react-query의 useQuery를 이용한 성공,에러,로딩 각 상황의 핸들링을 적용했다.
/user/logout 페이지 진입 시
const { data, isLoading, isError } = useQuery('logout', logoutApi);
위와 같은 코드로 queryKey가 'logout'인 쿼리를 생성한다.
useQuery는 옵션을 주지 않으면 생성과 동시에 두 번째 인자로 전달한 콜백함수를 실행하여 정보를 채우기 시작한다.
일반적으로 get 요청에서 쓰인다.
export const logoutApi = async () => {
await delay(1000);
// return { success: '로그아웃 성공' };
throw Error('Error');
};
export const delay = (time: number) =>
new Promise((resolve) => {
setTimeout(() => resolve('delay종료'), time);
});
setTimeout은 Promise 객체를 반환하지 않기 때문에 await
을 이용하여 딜레이 후 다음 코드를 실행할 수 없다.
따라서 delay 함수를 만들어 주고 logoutApi에 적용하여
1초 에러를 던지도록 했다.
따로 옵션을 설정하지 않으면
데이터 요청을 기본적으로 3번 하고 실패하면 에러로 처리한다.
세 번의 요청 후 에러처리되었고 에러페이지로 접근되었다.
로딩의 경우
if (isLoading) {
return <CircularProgress size={300} />;
}
위와 같이 처리하였으며 로딩중일 때 정상동작한다.
심심하지 않게 mui의 CircularProgress
를 이용하였다.
성공의 경우는 위에있는 LoginApi의 throw Error 부분
주석을 해제하고 실행하였다.
로그아웃에 성공하고 홈으로 1초 후 홈으로 이동하게 구현하였다.
'logout'쿼리의 값은 로그아웃이 성공하고 난 후 더 이상 필요가 없다고 판단해서 queryClient에서 'logout'을 키로 갖는 쿼리를 removeQueries 함수로 제거하였다.
useEffect의 return은 Unmount 될 때 실행되므로 로그아웃 페이지의 useEffect의 return에 콜백함수로 쿼리 제거코드를 넣었다.
확인을 위해 로그아웃 페이지에서
queryClient.getQueryData('logout');
위 코드를 콘솔로 찍고
같은 코드를 홈 화면에 임시로 구현한 버튼의 onClick 이벤트에서 콘솔로 찍게 하여 확인하였다.
결과 로그아웃페이지에서는 데이터가 찍히고
홈 화면에서 찍어보니 undefined가 찍혔다.
logout과 같이 사용하지 않는 값을 계속 갖고있기 보다는
바로 제거하는게 더 낫다고 판단했다.
성공 화면의 상단에 mui의 progressbar도 적용하여 심심하지 않게 구현했다..
react-query의 캐싱과 데이터재사용, refetch가 강점이라고 하는데 아직 이를 테스트해보지는 않았다.
fresh와 stale한 데이터일 경우를 만들어 refetch해서 새 데이터로 갈아끼우는 것도 추후에 진행해 봐야겠다
로그인페이지의 전체 코드는 다음과 같다
import { delay, getMyInfo, logoutApi } from '@utils/functions';
import { Button, Result } from 'antd';
import { useRouter } from 'next/router';
import { useQuery, useQueryClient } from 'react-query';
import 'antd/dist/antd.css';
import { CircularProgress, LinearProgress } from '@mui/material';
import { useEffect } from 'react';
const Logout = () => {
const { data, isLoading, isError } = useQuery('logout', logoutApi);
console.log(isLoading);
const router = useRouter();
const queryClient = useQueryClient();
useEffect(() => {
return () => queryClient.removeQueries('logout');
}, []);
if (isLoading) {
return <CircularProgress size={300} />;
}
if (isError) {
return (
<Result
status="error"
title="Submission Failed"
subTitle="Please check and modify the following information before resubmitting."
extra={[
<Button type="primary" key="console">
Go Console
</Button>,
<Button key="buy">Buy Again</Button>,
]}
></Result>
);
}
if (data?.success) {
(async () => {
await delay(1000);
queryClient.removeQueries('user');
router.push('/');
})();
return (
<>
<LinearProgress />
<Result
status="success"
title={
<>
<p>로그아웃 되었습니다!</p>
</>
}
subTitle={
<>
<p> 잠시 후 홈으로 이동합니다</p>
</>
}
/>
</>
);
}
};
export default Logout;
로딩과 성공 페이지는 얼추 꾸며놨는데 에러쪽은 antd에서 라이브데모로 구현해놓은 코드를 그대로 가져다 썻다.
Author And Source
이 문제에 관하여(react-query의 success, error, loading과 핸들링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@chad/react-query-success-error-loading-핸들링저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)