[project] useState& useRef 카메라Off 대체이미지

😎·2023년 1월 17일
0

PROJECT

목록 보기
15/26
post-thumbnail

✨ Camera on/off 대체이미지

📌

🚨열심히 프로젝트 중 예상치못한 오류가 발생했습니다 ....🚨
useState로 관리하던 users state가 값이 변경된 값이 참조가 안되는 경우가 있었는데요 열심히 구글링하고 찾아보니 useRef로 값을 저장해놓으면 리렌더링이 되어도 state의 값이 초기화 되지않고 변경된 값으로 유지가 가능하다고 하여 이용하였습니다!!


  function usePrevious(users) {
    const ref = useRef();
    useEffect(() => {
      ref.current = users;
    });
    return ref.current;
  }
  usePrevious(users);

🔧새로운 react hook 을 만들어서 user state 값이 초기화 되지않고 참조할수 있도록 작성하여 주었습니다!

  function onClickCameraOffHandler() {
    // eslint-disable-next-line no-use-before-define
    console.log(stream);
    stream.getVideoTracks().forEach((track) => {
      console.log(track);
      track.enabled = !track.enabled;
    });

    if (!cameraOff) {
      cameraBtn.current.innerText = '켜기';
      cameraOff = !cameraOff;
      videoRef.current.style.display = 'none';
      userCardImgRef.current.style.display = 'block';
      client.current.publish({
        destination: `/pub/chat/camera`,
        body: JSON.stringify({
          type: 'CAMERAOFF',
          nickname: myNickName,
          roomId: param.roomId,
        }),
      });
    } else {
      userCardImgRef.current.style.display = 'none';
      videoRef.current.style.display = 'block';
      cameraBtn.current.innerText = '끄기';
      client.current.publish({
        destination: `/pub/chat/camera`,
        body: JSON.stringify({
          type: 'CAMERAON',
          nickname: myNickName,
          roomId: param.roomId,
        }),
      });
      cameraOff = !cameraOff;
    }
  }

🔧 생각보다 길어진 유저 카메라 Off 핸들러 입니다 웹소켓을 활용하여 Camera를 Off 할때 게임방에 들어와 있는 멤버 전원에게 카메라를 Off 한 사용자의 nickName을 전송합니다.

  case 'CAMERAOFF': {
          // console.log(prevusers);
          console.log(data);
          setUsers((oldUsers) =>
            oldUsers.map((user) =>
              user.nickName === data.nickname
                ? { ...user, isCameraOn: false }
                : user,
            ),
          );
          console.log(users);

          break;
        }

🔧전송 받은 데이터를 활용하여 users state에서 해당 닉네임을 가진 사용자 객체의 isCameraOn 의 값을 false로 바꾸어줍니다


function Audio({ stream, nickName, isCameraOn, keyword }) {
  const videoRef = useRef(null);
  const userCardImgRef = useRef(null);
  const [userkeyword, setUserKeyword] = useState('키워드');
  const [userList, setUserList] = useState('');

  function cameraOnHandler() {
    if (isCameraOn === true) {
      videoRef.current.style.display = 'block';
      userCardImgRef.current.style.display = 'none';
    } else {
      videoRef.current.style.display = 'none';
      userCardImgRef.current.style.display = 'block';
    }
  }

  useEffect(() => {
    cameraOnHandler();
  }, [isCameraOn]);
  useEffect(() => {
    if (videoRef.current) {
      videoRef.current.srcObject = stream;
    }
    setUserKeyword(keyword[`${nickName}`]);
  }, [stream, keyword]);

🔧 Audio 컴포넌트는 해당 isCameraOn의 값을 props로 내려받는데요 해당 값이 false 일 경우 videoRef.current로 요소에 접근하여 style의 display를 none으로 바꾸어주고 대체할 이미지요소를 userCardImgRef.current 로 접근하여 style display를 block 으로 바꾸어 줍니다 : )

대체 이미지를 보여주기 위해 stream 으로 전송하는 fram의 값을 이미지 파일로 보내거나 하는 방식을 생각 해 보았는데.... mdn과 수많은 구글링을 시도해보았으나 찾지 못했습니다 ㅠㅠㅠ 결국 대체이미지를 보여주는 로직의 step이 좀 길어졌는데요
그래도 원하는 결과를 낼수 있어서 다행입니다 : )

profile
개발 블로그

0개의 댓글