소켓 - 채팅방 구현
io.connection → socket.~~~ 이런 느낌으로 이벤트? 키워드? 기반 소통
emit이 말하는거 on이 듣는거
socket.join 이부분 물어보기
import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import socket from '../../utils/socketServer';
export default function MyGroupPage() {
const { groupId } = useParams();
const [room, setRoom] = useState(null);
const navigate = useNavigate();
useEffect(() => {
// rooms 이벤트를 구독하고 데이터를 가져와서 room 상태 업데이트
const handleRooms = rooms => {
const filteredRoom = rooms.find(room => room.group === groupId);
if (filteredRoom) {
setRoom(filteredRoom);
}
};
socket.on('rooms', handleRooms);
// 컴포넌트 언마운트 시 이벤트 리스너 제거
}, []); // groupId가 변경될 때만 useEffect 실행
const handleChat = () => {
navigate(`/group/chat/${room?._id}`);
};
return (
<div>
<h1>{groupId}에 대한 상세 페이지 레고</h1>
<button onClick={handleChat}>채팅창 이동하기</button>
</div>
);
}
여기서 자꾸 room이 null로 설정된게 바뀌질 않음. room은 정상적으로 바뀌는데 랜더링 타이밍을 못맞춰서 자꾸 null로 들어가는거 같음
이거 개빡쳐서 그냥 group id를 chatpage에 넘겨서 room id를 찾는 로직을 chatpage에서 하는게 나을거같음
import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import socket from '../../utils/socketServer';
import { Button } from '@mui/base/Button';
import './index.css';
import InputField from './InputField/InputField';
import MessageContainer from './MessageContainer/MessageContainer';
import { useSelector } from 'react-redux';
const ChatPage = () => {
// console.log('유저정보는', user);
const user = useSelector(state => state.user?.userInfo);
const { groupId } = useParams(); // 유저가 조인한 방의 아이디를 url에서 가져온다
const [roomId, setRoomId] = useState(null);
const [chatLog, setChatLog] = useState([]); // 배열로 변경
const [message, setMessage] = useState('');
const navigate = useNavigate();
// 채팅창 떠날 때
const leaveRoom = () => {
socket.emit('leaveRoom', user, res => {
if (res.ok) navigate(-1); // 다시 채팅방 리스트 페이지로 돌아감
});
};
// console.log('message List', chatLog);
// console.log('룸아이디???', roomId);
// 채팅 화면 처음 들어올 때
useEffect(() => {
const handleRooms = rooms => {
setRoomId(rooms.find(room => room.group === groupId)._id);
};
socket.on('rooms', handleRooms);
return () => {
socket.off('rooms', handleRooms);
};
}, []);
useEffect(() => {
socket.on('message', message => {
// message 이벤트를 수신하면 이 함수가 실행됩니다.
// 여기서 message는 서버에서 보낸 데이터입니다.
console.log('서버로부터 메시지 수신:', message, '라고?');
setChatLog(prevState => prevState.concat(message));
});
// 서버에서 이전 채팅 로그를 받아온다
}, [message]);
useEffect(() => {
console.log('유저는>>', user);
socket.emit('joinRoom', user, roomId, res => {
if (res && res.ok) {
console.log('successfully join', res);
} else {
console.log('fail to join', res);
}
});
socket.emit('getChatLog', roomId, res => {
if (res?.isOk) {
console.log('서버에서 받은 채팅 로그:', res.data);
setChatLog(prevState => prevState.concat(res.data));
}
});
}, [roomId]);
const sendMessage = event => {
event.preventDefault();
socket.emit('sendMessage', roomId, message, res => {
if (!res.ok) {
console.log('error message', res.error);
}
setMessage('');
});
};
return (
<div>
<div className="App">
<nav>
<Button onClick={leaveRoom} className="back-button">
←
</Button>
<div className="nav-user">{user.nick_name}</div>
</nav>
<div>{chatLog.length > 0 ? <MessageContainer chatLog={chatLog} user={user} /> : null}</div>
<InputField message={message} setMessage={setMessage} sendMessage={sendMessage} />
</div>
</div>
);
};
export default ChatPage;
이렇게 바꿔서 되긴 했음…….. 안됐음 ㅜㅜㅜㅜ
백에 요청 응답 방식으로 roomId 얻어옴.. 소켓으로 통신한 결과를 setState 하려면 어떻게 해야하는지 알아보기!