(펌)개념 정리

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;
`