(펌)개념 정리
React soket.io connect하기
ble194
2022. 9. 2. 12:46
백엔드 분이 룸도 다 만들어주셔서 나는 해당 룸으로 밀어넣어주고 연결만 시켜주면됐다.
하지만 connect를 할때에 랜더링이 두번 일어나서 랜더링 될 때마다 사람마다 soket을 요청하는 soket의 id가 바뀌었다.
그래서 랜더링의 영향을 받지않게 할 방법을 생각하다가 함수형 컴포넌트 안에서 connect를 연결하니까 컴포넌트 랜더링시 다시 연결하면서 id가 바뀐다는 것을 깨달았고, import처럼 컴포넌트 밖에서 connect 요청을 하니까 해결이 되었다.
import React, { useEffect, useState, useRef } from "react";
import styled from "styled-components";
import socketio from 'socket.io-client';
import { useParams } from "react-router-dom";
const socket = socketio.connect(process.env.REACT_APP_SURVER); //백서버
function Room() {
const params = useParams();
const roomId = +params.roomId;
const room = roomId;
const token = process.env.REACT_APP_TOKEN;
const [userId, setUserId] = useState('');
const [nickname, setNickname] = useState('게스트');
const [masterNickname, setMasterNickname] = useState('방장');
const [kicksocketId, setKicksocketId] = useState('');
const [mysocketId, setMysocketId] = useState('');
//채팅
const [chat, setChat] = useState(""); // 새로운 채팅
const [list, setList] = useState([]); // 채팅 list
const [users, setUsers] = useState([]); // 유저 list
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current.scrollIntoView({ behavior: "smooth" })
}
//진행
const [ready, setReady] = useState(false); // 새로운 채팅
useEffect(() => {
socket.emit("login",
{
userId,
nickname,
room
}, () => {
}
);
socket.on("login", chat => {
setList(prev => prev.concat({ text: chat }));
});
socket.on("chat", chat => {
setList(prev => prev.concat({ text: chat.msg }));
});
}, []);
useEffect(scrollToBottom, [list]);
return (
<div style={{ "backgroundColor": "black" }}>
<RoomBody>
{nickname === masterNickname ?
//방장 구역
<div>
<div>{masterNickname}님의 게임방
<span>
<button>게임시작</button>
<button>나가기</button>
</span>
</div>
<div>{masterNickname}
<span>방장</span>
<span>준비완료</span>
</div>
<div>{users.filter((user) => user.nickname !== masterNickname)[0].nickname !== undefined ? users.filter((user) => user.nickname !== masterNickname)[0].nickname : ''}
<span>
<button>추방하기</button>
</span>
<span>{ready === true ? "준비완료" : "준비중"}</span>
</div>
</div> :
//게스트 구역
<div>
<div>{masterNickname}님의 게임방
<span>
<button>준비하기</button>
<button>나가기</button>
</span>
</div>
<div>{masterNickname}
<span>/방장/</span>
<span>준비완료</span>
</div>
<div>{nickname}
<span>/나/</span>
<span>{ready === true ? "준비완료" : "준비중"}</span>
</div>
</div>
}
</RoomBody>
<ChatBody>
<span>{roomId}번 방입니다.</span>
<ChatWrapCss>
{list.map((item, index) => (
<p key={index}>
{item.text}
</p>
))}
<div ref={messagesEndRef} />
</ChatWrapCss>
<form
onSubmit={e => {
e.preventDefault();
socket.emit("chat", { msg: chat });
setChat("");
}}
>
<div>
<input placeholder="메세지를 입력해주세요." value={chat} onChange={e => setChat(e.target.value)} /><span>
<button>전송</button>
</span>
</div>
</form>
</ChatBody >
</div>
);
};
export default Room;
const ChatWrapCss = styled.div`
overflow-y: scroll;
border: "1px solid";
padding: 3px;
height: 200px;
p {
height:5px;
}
`
const ChatBody = styled.div`
width: 800px;
height: 200px;
background-color: red;
margin: auto;
display: flex;
flex-direction: column;
input {
width: 749px;
height: 20px;
}
`
const RoomBody = styled.div`
width: 800px;
height: 350px;
background-color: yellow;
margin: auto;
`