이 글은 아래 문서를 간단히 요약 후 번역한 것입니다.
https://dev.to/bravemaster619/how-to-use-socket-io-client-correctly-in-react-app-o65
웹 캐치마인드 게임 Scramble 코드를 짜다가, Socket.io를 React에서 어떻게 사용하면 좋을까 고민하던 중 도움이 된 아티클을 번역하였습니다. 프로젝트 규모가 작고, 클라이언트에 Socket 인스턴스가 하나만 필요한 경우 유용합니다. 좀 더 규모가 큰 프로젝트에서 Socket.io 사용에 대해 고민하는 경우 아래 문서가 도움이 될 수 있습니다.
오류가 있다면 댓글로 알려주세요!
하나의 전역 소켓 인스턴스 관리를 위해 React.js의 Context API를 사용하는 방법을 알아봅시다. 이 글을 읽기에 앞서 React의 라이프 사이클, ContextAPI 등에 대한 기본적인 이해가 필요합니다.
React.js의 useContext Hook을 사용하여 어플리케이션 전체에 SocketContext를 제공합시다.
다음과 같은 위치에 아래와 같이 파일을 생성해보세요. context/socket.js
import socketio from "socket.io-client";
import { SOCKET_URL } from "config";
export const socket = socketio.connect(SOCKET_URL);
export const SocketContext = React.createContext();
import {SocketContext, socket} from 'context/socket';
import Child from 'components/Child';
const App = () => {
return (
<SocketContext.Provider value={socket}>
<Child />
<Child />
...
</SocketContext.Provider
);
};
여기까지 작업이 끝났다면, 이제 App의 모든 자식 요소에서 소켓을 사용할 수 있습니다.
child
, grandChild
등 모든 하위 요소에서 다음과 같이 소켓을 사용할 수 있습니다.
import React, {useState, useContext, useCallback, useEffect} from 'react';
import {SocketContext} from 'context/socket';
const GrandChild = ({userId}) => {
const socket = useContext(SocketContext);
const [joined, setJoined] = useState(false);
const handleInviteAccepted = useCallback(() => {
setJoined(true);
}, []);
const handleJoinChat = useCallback(() => {
socket.emit("SEND_JOIN_REQUEST");
}, []);
useEffect(() => {
// as soon as the component is mounted, do the following tasks:
// emit USER_ONLINE event
socket.emit("USER_ONLINE", userId);
// subscribe to socket events
socket.on("JOIN_REQUEST_ACCEPTED", handleInviteAccepted);
return () => {
// before the component is destroyed
// unbind all event handlers used in this component
socket.off("JOIN_REQUEST_ACCEPTED", handleInviteAccepted);
};
}, [socket, userId, handleInviteAccepted]);
return (
<div>
{ joined ? (
<p>Click the button to send a request to join chat!</p>
) : (
<p>Congratulations! You are accepted to join chat!</p>
) }
<button onClick={handleJoinChat}>
Join Chat
</button>
</div>
);
};
JWT 토큰을 이용한 소켓 연결이 필요하다면 아래와 같이 작성하세요.
const getSocket = () => {
const token = getAuthToken(); // get jwt token from local storage or cookie
if (token) {
return socketio.connect(SOCKET_URL, {
query: { token }
});
}
return socketio.connect(SOCKET_URL);
};
그 후 서버에서 다음과 같이 JWT 토큰을 받아올 수 있습니다.
import SocketIO from "socket.io";
const io = new SocketIO.Server(expressApp);
const jwtMiddleware = (socket, next) => {
const {token} = socket.handshake.query;
// verify token
};
io.use(jwtMiddleware);
큰 규모 프로젝트 예시 링크 죽었어요!