관리 메뉴

즐겁게, 코드

리액트 & socket.io 기반 채팅 어플리케이션 만들기 - 클라이언트 편 본문

💻 백엔드/Node.js

리액트 & socket.io 기반 채팅 어플리케이션 만들기 - 클라이언트 편

Chamming2 2021. 2. 3. 16:58

서버 편 과 이어지는 글로, 클라이언트 제작 과정을 여기서 정리하려 했지만 너무 분량이 길어져 중요한 부분만 짚기로 하였습니다.

전체 서버 & 클라이언트 코드는 아래 깃허브 저장소 링크에서 확인할 수 있습니다.

 

C17AN/react-socket-chat

socket.io와 리액트를 활용한 채팅 어플리케이션. Contribute to C17AN/react-socket-chat development by creating an account on GitHub.

github.com

이 글에서는 리액트 클라이언트에서 socket.io-client를 활용하는 팁만을 다룹니다.

1. 클라이언트와 서버 연결하기 - 언제나 훅을 사용하자

클라이언트에서는 socket.io-client에서 불러온 객체를 활용해 서버와 연결할 수 있습니다.

import React from "react";
import socketIOClient from "socket.io-client";

const socket = socketIOClient("localhost:5000");

const Chat = () => {
  return (
    <div>Chat</div>
  )
};

export default Chat;

리액트에서 socket.io를 사용하는 많은 예제들이 재렌더링 시 함수가 호출되는 문제를 방지하기 위해 컴포넌트 밖에서 소켓 연결을 시도하는데요, 이 방법은 react-router-dom 라이브러리와 함께 사용했을 때 버그가 일어날 수 있습니다.

 

(* 원래대로면 '/Chat' 경로의 Chat 컴포넌트에서만 소켓 연결이 수행되어야 하지만, 소켓을 이렇게 연결하면 다른 경로의 컴포넌트를 렌더링해도 소켓 연결이 수행됩니다. -> 아마 라우터가 전체 경로를 훑는 과정에서 컴포넌트 바깥의 구문을 실행하는 것이 아닐까 싶습니다.*) 

 

따라서 저는 이 방법보다는 리액트 훅을 사용하는 방법을 추천드립니다.

import React, { useEffect, useState } from "react";
import socketIOClient from "socket.io-client";

const Chat = () => {
  const [currentSocket, setCurrentSocket] = useState();

  useEffect(() => {
    setCurrentSocket(socketIOClient("localhost:5000"));
  }, []);

  return (
    <ChatInput socket = {currentSocket} />
  )
};

export default Chat;

이렇게 훅을 사용해서 소켓을 관리하면 렌더링에 따른 소켓 연결 상태를 확실히 예측할 수 있습니다.

2. 조건부 렌더링 활용하기

하지만 위 코드의 ChatInput 컴포넌트에서 socket 속성을 활용하려 하면 can't ~~~ undefined 오류가 출력될 것입니다.

이는 useState로 상태값을 변경하는 동안 아주 미세한 텀이 있기 때문인데, 이를 처리하기 위해 조건부 렌더링을 활용하면 됩니다.

import React, { useEffect, useState } from "react";
import socketIOClient from "socket.io-client";
import ChatLog from "../../components/ChatLog/ChatLog";
import Loading from "./Loading";

const Chat = () => {
  const [currentSocket, setCurrentSocket] = useState();

  useEffect(() => {
    setCurrentSocket(socketIOClient("localhost:5000"));
  }, []);
  
  return (
    <div>
      // 소켓 연결이 완료되기 전까지는 Loading 컴포넌트를 렌더링함.
      {currentSocket ? (
          <ChatLog socket={currentSocket} />
      ) : (
        <Loading></Loading>
      )}
    </div>
  );
};

export default Chat;

이제 컴포넌트가 렌더링될때만 서버와 클라이언트가 연결되며 채팅 앱을 만들 준비가 모두 끝났습니다.

서버와의 연결은 확실히 성공했으니, 메시지 관리 등 컴포넌트별 기능은 로직은 입맛에 맞게 구성하시면 됩니다. 😃

 

2021. 08.04 : CORS 설정이 socket.io에 되어있지 않은 문제가 있어 수정했습니다!

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆