import { AxiosResponse } from 'axios';
import { deleteAPI, getAPI, putAPI } from './axios';
import { Notifications } from '@/types/header';
export const informApis = {
notification: async (): Promise<Notifications[]> => {
const response: AxiosResponse<Notifications[]> = await getAPI('/api/notification');
return response.data;
},
// AxiosResponse는 Axios 라이브러리에서 제공하는 타입으로 HTTP 응답을 나타냄
// 이 타입을 사용함으로써 HTTP 응답의 형식을 정확하게 지정
notificationRead: async (username: string) =>
await putAPI(`/api/notification/${username}/read`),
notificationDelete: async (id: number) =>
await deleteAPI(`/api/notification/${id}/delete`),
};
useQuery**는: 데이터를 읽는 작업에 적합, 자동 캐싱, 상태 관리 등 제공useMutation**은 데이터를 변경하는 작업에 적합, 변경에 따른 사이드 이펙트 관리 기능 제공export const useGetMessageAlert = () => {
return useQuery('alertList', informApis.notification);
};
export function usePutReadAlert() {
return useMutation((username:string) => {
return informApis.notificationRead(username);
});
}
export function useDeleteAlert() {
return useMutation((id:number) => {
return informApis.notificationDelete(id);
});
}
React Query 사용한 이유
기본 Axios 요청(get, delete 등)과 비교했을 때 상태 관리, 자동화, 성능 최적화 측면에서 이점을 제공하기 때문 사용
상태 관리
기본 Axios 요청을 사용할 때는 데이터 로딩, 성공, 에러 상태를 수동으로 관리해야 한다.
React Query는 이러한 상태 관리를 자동화하고, 데이터 캐싱 및 동기화를 제공하여 개발자의 부담을 줄여준다.
자동 업데이트 및 캐싱
Axios로 데이터를 요청하면, 새로운 데이터를 반영하기 위해 수동으로 새로고침이나 재요청 해야 한다. React Query는 자동으로 데이터를 업데이트하고 캐싱하여, 최신 데이터가 항상 UI에 반영해준다.
성능 최적화
기본 Axios 요청은 중복 요청과 관련된 성능 문제를 해결하기 어렵지만, React Query는 캐싱과 데이터 재사용을 통해 불필요한 네트워크 요청을 줄이고 성능을 최적화한다.
useEffect를 사용하여 token이 있을 때만 sse 연결
useEffect(() => {
if (token) {
const eventSource = new EventSourcePolyfill(
`${API_BASE_URL}/api/subscribe`,
{
headers: {
Authorization: token,
'Content-Type': 'text/event-stream',
Connection: 'keep-alive',
'Cache-Control': 'no-cache',
},
reconnectInterval: 5000, // 5초 후 재연결 시도
heartbeatTimeout: 3600000, // 1시간 타임아웃 설정
},
);
EventSourcePolyfill
EventSource API는 HTTP 요청 헤더를 설정할 수 있는 기능을 지원하지 않기 때문에 eventSource를 확장하여 HTTP 헤더를 설정할 수 있는 기능을 제공
// 연결확인
eventSource.onopen = () => {
// console.log('SSE 연결됨');
// console.log('allList', allList);
};
// 서버로부터 새로운 알림 데이터를 받아오기
eventSource.addEventListener('sse', event => {
const messageEvent = event as MessageEvent;
const parsedData = JSON.parse(messageEvent.data);
if (parsedData.content === 'send dummy data to client.') {
// console.log('더미데이터는 무시하겠다.')
return;
}
setNewAlert(prev => [...prev, parsedData]);
// console.log('새로운 알림',newAlert);
queryClient.invalidateQueries('alertList');
});