Immer를 활용한 실시간 채팅 애플리케이션 구현하기

소개

이번 포스트에서는 Immer라는 JavaScript 라이브러리를 활용하여 실시간 채팅 애플리케이션을 구현해 보겠습니다. Immer는 불변성을 유지하면서도 간단하게 상태를 변경할 수 있는 편리한 도구입니다.

필요한 도구들

이 프로젝트를 위해서는 다음과 같은 도구들이 필요합니다:

프로젝트 구조 설정

먼저, React 프로젝트를 생성합니다:

npx create-react-app chat-app
cd chat-app

그리고 필요한 라이브러리를 설치합니다:

npm install immer socket.io-client

상태 관리 설정

Immer를 이용하여 상태 관리를 위한 state 객체를 생성합니다. 아래는 예시 코드입니다.

import produce from 'immer';

const initialState = {
  messages: [],
  typing: false
};

const reducer = (state = initialState, action) => {
  return produce(state, draft => {
    switch(action.type) {
      case 'SEND_MESSAGE':
        draft.messages.push(action.payload);
        break;
      case 'SET_TYPING':
        draft.typing = action.payload;
        break;
      default:
        break;
    }
  });
};

export default reducer;

실시간 통신 설정

Socket.io를 사용하여 실시간 통신을 설정합니다. 클라이언트 측에서는 다음과 같은 코드를 작성합니다:

import io from 'socket.io-client';

const socket = io('http://localhost:3000');

socket.on('receiveMessage', message => {
  dispatch({ type: 'SEND_MESSAGE', payload: message });
});

socket.on('typing', isTyping => {
  dispatch({ type: 'SET_TYPING', payload: isTyping });
});

서버 측에서는 다음과 같은 코드를 작성합니다:

const http = require('http');
const socketio = require('socket.io');

const server = http.createServer();
const io = socketio(server);

io.on('connection', socket => {
  socket.on('sendMessage', message => {
    io.emit('receiveMessage', message);
  });

  socket.on('typing', isTyping => {
    io.emit('typing', isTyping);
  });
});

server.listen(3000, () => {
  console.log('Server listening on port 3000');
});

채팅 인터페이스 구현

마지막으로, 채팅 인터페이스를 구현합니다. 이 부분은 React 컴포넌트를 활용하여 구현하면 됩니다. 예를 들어, 다음과 같이 채팅 메시지와 입력 필드를 구현할 수 있습니다:

import React, { useState } from 'react';

const ChatApp = () => {
  const [message, setMessage] = useState('');
  const [isTyping, setIsTyping] = useState(false);
  const [state, dispatch] = useReducer(reducer, initialState);

  const handleTyping = () => {
    if (message) {
      setIsTyping(true);
      socket.emit('typing', true);

      setTimeout(() => {
        setIsTyping(false);
        socket.emit('typing', false);
      }, 2000);
    } else {
      setIsTyping(false);
      socket.emit('typing', false);
    }
  };

  const handleSendMessage = () => {
    if (message) {
      socket.emit('sendMessage', message);
      setMessage('');
    }
  };

  return (
    <div>
      <div>
        {state.messages.map(message => (
          <div key={message.id}>{message.text}</div>
        ))}
      </div>
      <div>
        <input type="text" value={message} onChange={(e) => setMessage(e.target.value)} onKeyUp={handleTyping} />
        <button onClick={handleSendMessage}>Send Message</button>
      </div>
      {isTyping && <div>상대방이 입력 중입니다.</div>}
    </div>
  );
};

export default ChatApp;

결론

이렇게 Immer를 활용하여 실시간 채팅 애플리케이션을 구현해 보았습니다. Immer를 사용하면 상태 관리를 더 쉽게 할 수 있고, Socket.io를 이용하여 실시간 통신을 구현할 수 있습니다. 이를 참고하여 자신만의 채팅 애플리케이션을 만들어 보세요!

#Immer #실시간채팅