From b292191849b2676ae1c884854349d5b16b1be9d5 Mon Sep 17 00:00:00 2001 From: novice1993 Date: Tue, 3 Oct 2023 01:33:59 +0900 Subject: [PATCH] =?UTF-8?q?[Refactor]=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=ED=86=B5=EC=8B=A0=20=ED=9A=A8=EC=9C=A8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 서버 데이터 변화 없을 경우 api 호출하지 않고 기존에 캐싱했던 데이터 활용하도록 기능 구현 (React-Query 라이브러리 기능 활용) Issues #122 --- client/src/hooks/useCompanyData.ts | 35 ++++++++++++++++------------- client/src/hooks/useGetStockData.ts | 17 +++++++------- client/src/hooks/useGetStockInfo.ts | 15 +++++++------ client/src/main.tsx | 8 ++++++- 4 files changed, 43 insertions(+), 32 deletions(-) diff --git a/client/src/hooks/useCompanyData.ts b/client/src/hooks/useCompanyData.ts index 5decdc9b..af35630e 100644 --- a/client/src/hooks/useCompanyData.ts +++ b/client/src/hooks/useCompanyData.ts @@ -1,19 +1,7 @@ -import { useQuery } from 'react-query'; -import axios from 'axios'; +import { useQuery } from "react-query"; +import axios from "axios"; -const BASE_URL = 'http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080'; - -// 데이터 타입 정의 -type CompanyData = { - companyId: number; - code: string; - korName: string; - stockInfResponseDto: { - stck_prpr: string; - prdy_vrss: string; - prdy_ctrt: string; - }; -}; +const BASE_URL = "http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080"; // 커스텀 훅 정의 function useCompanyData(startCompanyId: number, endCompanyId: number) { @@ -28,10 +16,13 @@ function useCompanyData(startCompanyId: number, endCompanyId: number) { // 리액트-쿼리의 useQuery 훅 사용 const { data, isLoading, isError } = useQuery( - ['companyData', startCompanyId, endCompanyId], + "companyData", async () => { const promises = companyIds.map((companyId) => fetchData(companyId)); return Promise.all(promises); + }, + { + staleTime: Infinity, } ); @@ -55,3 +46,15 @@ function useCompanyData(startCompanyId: number, endCompanyId: number) { } export default useCompanyData; + +// 데이터 타입 정의 +type CompanyData = { + companyId: number; + code: string; + korName: string; + stockInfResponseDto: { + stck_prpr: string; + prdy_vrss: string; + prdy_ctrt: string; + }; +}; diff --git a/client/src/hooks/useGetStockData.ts b/client/src/hooks/useGetStockData.ts index d8812823..409e1c12 100644 --- a/client/src/hooks/useGetStockData.ts +++ b/client/src/hooks/useGetStockData.ts @@ -9,12 +9,6 @@ const useGetStockData = (companyId: number) => { const [autoRefetch, setAutoRefetch] = useState(false); const queryClient = useQueryClient(); - // 시간대 (timeZone) 별로 queryKey를 다르게 설정해서, 서버 데이터가 동일할 때는 캐싱된 데이터 활용하고 서버 데이터가 갱신됐을 때는 새롭게 받아옴 (서버 데이터 30분마다 갱신) - const currentTime = new Date(); - const [month, day, hour, minute] = [currentTime.getMonth(), currentTime.getDate(), currentTime.getHours(), currentTime.getMinutes()]; - const timeZone = minute === 0 || minute === 30 ? "30 or 60" : 0 < minute && minute < 30 ? "1~29" : "31~59"; - const queryKey = `${month}월 ${day}일 ${hour}시 ${timeZone}`; - // 1) 주말, 공휴일 여부 체크 const today = new Date(); const isBusinessDay = !isHoliday(today, { include: { saturday: true, sunday: true } }); // 토요일, 일요일, 공휴일 (임시 공휴일 포함) @@ -28,6 +22,12 @@ const useGetStockData = (companyId: number) => { const dataRenewalTime = isBusinessDay || !marketCloseTime; + // 시간대 (timeZone) 별로 queryKey를 다르게 설정해서, 서버 데이터가 동일할 때는 캐싱된 데이터 활용하고 서버 데이터가 갱신됐을 때는 새롭게 받아옴 (서버 데이터 30분마다 갱신) + const currentTime = new Date(); + const [month, day, hour, minute] = [currentTime.getMonth(), currentTime.getDate(), currentTime.getHours(), currentTime.getMinutes()]; + const timeZone = minute === 0 || minute === 30 ? "30 or 60" : 0 < minute && minute < 30 ? "1~29" : "31~59"; + const queryKey = dataRenewalTime ? `chartData${companyId} ${month}월 ${day}일 ${hour}시 ${timeZone}` : `chartData${companyId}`; + // 개장 시간 이내일 경우, 현재 시각이 30분, 정각이 아닌 경우 남은 시간 계산하여 checkTime 함수 다시 실행 useEffect(() => { if (dataRenewalTime) { @@ -49,8 +49,9 @@ const useGetStockData = (companyId: number) => { } }, []); - const { data, isLoading, error, refetch } = useQuery(`chartData${companyId} ${queryKey}`, () => getChartData(companyId), { - enabled: true, + const { data, isLoading, error, refetch } = useQuery(queryKey, () => getChartData(companyId), { + staleTime: Infinity, + cacheTime: Infinity, refetchInterval: autoRefetch && dataRenewalTime ? 60000 * 30 : false, // 정각 혹은 30분에 맞춰서 30분 마다 데이터 리패칭 onSuccess: () => { queryClient.invalidateQueries("stockInfo"); diff --git a/client/src/hooks/useGetStockInfo.ts b/client/src/hooks/useGetStockInfo.ts index df72266d..71205c30 100644 --- a/client/src/hooks/useGetStockInfo.ts +++ b/client/src/hooks/useGetStockInfo.ts @@ -8,12 +8,6 @@ const url = "http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080 const useGetStockInfo = (companyId: number) => { const [autoRefetch, setAutoRefetch] = useState(false); - // 시간대 (timeZone) 별로 queryKey를 다르게 설정해서, 서버 데이터가 동일할 때는 캐싱된 데이터 활용하고 서버 데이터가 갱신됐을 때는 새롭게 받아옴 (서버 데이터 30분마다 갱신) - const currentTime = new Date(); - const [month, day, hour, minute] = [currentTime.getMonth(), currentTime.getDate(), currentTime.getHours(), currentTime.getMinutes()]; - const timeZone = minute === 0 || minute === 30 ? "30 or 60" : 0 < minute && minute < 30 ? "1~29" : "31~59"; - const queryKey = `${month}월 ${day}일 ${hour}시 ${timeZone}`; - // 1) 주말, 공휴일 여부 체크 const today = new Date(); const isBusinessDay = !isHoliday(today, { include: { saturday: true, sunday: true } }); // 토요일, 일요일, 공휴일 (임시 공휴일 포함) @@ -27,6 +21,12 @@ const useGetStockInfo = (companyId: number) => { const dataRenewalTime = isBusinessDay || !marketCloseTime; + // 시간대 (timeZone) 별로 queryKey를 다르게 설정해서, 서버 데이터가 동일할 때는 캐싱된 데이터 활용하고 서버 데이터가 갱신됐을 때는 새롭게 받아옴 (서버 데이터 30분마다 갱신) + const currentTime = new Date(); + const [month, day, hour, minute] = [currentTime.getMonth(), currentTime.getDate(), currentTime.getHours(), currentTime.getMinutes()]; + const timeZone = minute === 0 || minute === 30 ? "30 or 60" : 0 < minute && minute < 30 ? "1~29" : "31~59"; + const queryKey = dataRenewalTime ? `chartData${companyId} ${month}월 ${day}일 ${hour}시 ${timeZone}` : `chartData${companyId}`; + // 개장 시간 이내일 경우, 현재 시각이 30분, 정각이 아닌 경우 남은 시간 계산하여 checkTime 함수 다시 실행 useEffect(() => { if (dataRenewalTime) { @@ -49,7 +49,8 @@ const useGetStockInfo = (companyId: number) => { }, []); const { data, isLoading, error, refetch } = useQuery(`stockInfo${companyId} ${queryKey}`, () => getStockInfo(companyId), { - enabled: true, + staleTime: Infinity, + cacheTime: Infinity, refetchInterval: autoRefetch && dataRenewalTime ? 60000 * 30 : false, // 정각 혹은 30분에 맞춰서 30분 마다 데이터 리패칭 }); diff --git a/client/src/main.tsx b/client/src/main.tsx index 552a328a..938e721e 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -6,7 +6,13 @@ import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import store from "./store/config.ts"; -const queryClient = new QueryClient(); +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + }, + }, +}); ReactDOM.createRoot(document.getElementById("root")!).render( <>