어떤 페이지에서 사용자가 새로고침을 할 지 모르기 때문에 페이지를 이동 할 때마다 구독과 구독해제를 하도록 구현 했다.
import StompJs from 'stompjs';
import SockJS from 'sockjs-client';
import { useDispatch, useSelector } from 'react-redux';
import { getToken } from '../utils/auth';
import T from '../api/tokenInstance';
import { setNoti } from '../features/notice/actions';
// 변수 및 함수 선언, useEffect
const isNoti = useSelector((state) => state.notice.isGlobalNoti);
const sock = new SockJS(`${baseURL}/ws-stomp`);
const ws = StompJs.over(sock);
const token = getToken();
const wsConnectSubscribe = React.useCallback(async () => {
if (!token) {
return null;
}
try {
const { data } = await T.GET('/auth');
console.log(data);
ws.connect({}, () => {
ws.subscribe(
`/user/sub/user`,
() => {
if (!isNoti) {
dispatch(setNoti(true));
}
},
{ token, userEmail: data.email },
);
});
} catch (error) {
console.log(error);
}
return null;
}, []);
const wsDisConnectUnsubscribe = React.useCallback(() => {
try {
ws.disconnect(
() => {
ws.unsubscribe('sub-0');
},
// { token }
);
} catch (error) {
console.log(error);
}
}, []);
React.useEffect(() => {
if (!token) {
return null;
}
wsConnectSubscribe();
return () => {
wsDisConnectUnsubscribe();
};
}, []);
소켓에 연결하는 위의 로직을 모든 페이지에 추가하다가 문득 이런 상황에 커스텀 훅을 써야하지 않을까 싶어서 항상 생각만 하던 커스텀 훅을 직접 만들어 보았다.
// useSocketNotiRoom.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import StompJs from 'stompjs';
import SockJS from 'sockjs-client';
import { getToken } from '../utils/auth';
import T from '../api/tokenInstance';
import { setNoti } from '../features/notice/actions';
const baseURL = process.env.REACT_APP_SERVER_URI;
export default function useSocketNotiRoom() {
const dispatch = useDispatch();
const isNoti = useSelector((state) => state.notice.isGlobalNoti);
const sock = new SockJS(`${baseURL}/ws-stomp`);
const ws = StompJs.over(sock);
const token = getToken();
const wsConnectSubscribe = React.useCallback(async () => {
if (!token) {
return null;
}
try {
const { data } = await T.GET('/auth');
console.log(data);
ws.connect({}, () => {
ws.subscribe(
`/user/sub/user`,
() => {
if (!isNoti) {
dispatch(setNoti(true));
}
},
{ token, userEmail: data.email },
);
});
} catch (error) {
console.log(error);
}
return null;
}, []);
const wsDisConnectUnsubscribe = React.useCallback(() => {
try {
ws.disconnect(() => {
ws.unsubscribe('sub-0');
});
} catch (error) {
console.log(error);
}
}, []);
return [wsConnectSubscribe, wsDisConnectUnsubscribe, token];
}
페이지에서 직접 호출해서 사용해 보니 잘 동작해서 너무 뿌듯했다. 왜 쓰는지, 왜 필요한지도 모르고 사용하기 싫어서 한번도 쓰지 않았는데 직접 만들어서 쓰니 이해가 되는거 같기도 하고 그렇다. 근데 이렇게 쓰는게 맞는지 검증할 방법이 없어서 조금 애매하긴 하네 ㅎ..
아래와 같이 쓰기만 하면 끝나서 정말 많은 코드가 줄어들었다 !
import useSocketNotiRoom from '../hooks/useSocketNotiRoom';
// 커스텀 훅 호출, useEffect
const [wsConnectSubscribe, wsDisConnectUnsubscribe, token] =
useSocketNotiRoom();
React.useEffect(() => {
if (!token) {
return null;
}
wsConnectSubscribe();
return () => {
wsDisConnectUnsubscribe();
};
}, []);
소켓에 관해서 많이 공부하고 갑니다 !!!