오늘은 내 인생 첫 기업 면접을 보게된 날이다. 면접이 끝날 무렵 면접관님께서 혼자 만들어본 칸반보드에 대해 피드백을 주셨는데 브라우저를 종료시켜 유저가 소켓 통신을 종료하는 부분에서 useEffect에서 의존성 배열을 넣지 않는 것 보단, return문을 활용하면 좋을것 같다는 피드백을 남겨주셨고 면접이 종료되고 집에 오자마자 관련된 내용을 찾아보았다.
우선 useEffect에 return문을 사용하는 것은 Clean-up 이라는 키워드 였는데 컴포넌트가 언마운트가 되면 실행 시킬 코드를 return문에 넣어주면 된다. 이걸 사용하는 이유는 정리가 필요한 side effect라는 기능이 있기 때문인데 여기서 side effect는 데이터 가져오기, 구독 설정하기, 수동으로 React 컴포넌트의 DOM을 수정하는 것 등등이 있다고 한다.
모든 side effect가 Clean-up이 필요한 것은 아니고 네트워크 리퀘스트, DOM 수동 조작, 로깅 이런 것들은 Clean-up이 필요하지 않다고 한다.
useEffect(() => {
console.log('컴포넌트가 화면에 나타남');
return () => {
console.log('컴포넌트가 화면에서 사라짐');
};
}, []);
이런 코드이려나
언급된 코드는 다음과 같았다.
//접속 종료시
useEffect(() => {
socket.on("left", (data) => {
setUserList(
Array.from(data).filter(
(x) => JSON.stringify(x) !== JSON.stringify(num.current)
)
);
});
});
처음에 코드를 짰을 때, 접속 종료라는건 언제나 일어날 수 있는 행위이기에 의존성 배열을 딱히 넣지 않고 렌더링 될 때마다 감시하면 되겠지 라는 막연한 생각으로 이렇게 짰던 것 같다.
하지만 이 코드가 Clean-up을 사용하기엔 적절하지 않았다. 이 useEffect가 하는 일은 다른 유저가 접속을 종료했을 때 서버에서 정의해둔 left 이벤트를 받아와서 단순히 userList라는 state를 변경해 주는 함수에 불과하기 때문이다. 정리하자면, 접속을 종료하는 이벤트는 서버에 정의되어 있고 프론트에서는 소켓이 변할 때 마다 접속을 종료한 유저의 컴포넌트는 신경쓸 필요 없이 남아있는 유저의 화면만 신경써주면 되기 때문에 언마운트 될 때 실행할 것도 없고, Clean-up이 필요한 것 같지 않았다.
socket.on("disconnect", () => {
if (!user) {
return false;
}
userList.splice(userList.indexOf(user), 1);
io.emit("left", userList);
});
서버에 정의해둔 disconnect 이벤트
하지만 어느 정도의 코드 리팩토링을 수행했다. 접속과 종료가 각각 하나의 useEffect로 선언되어 동작 했었는데 천천히 코드를 살펴보니 종료에 해당되는 useEffect의 의존성 배열에 socket값이 들어가야 된다는 것을 깨닳았고, 만약 그렇게 된다면 접속쪽 코드와 종료쪽 코드가 일치하는 부분이 많아서 하나로 합칠 수 있다는 것을 깨닳았다.
/** 접속중인 유저 리스트 변경 */
const editUserList = (data) => {
setUserList(
Array.from(data).filter(
(x) => JSON.stringify(x) !== JSON.stringify(num.current)
)
);
};
//접속 혹은 종료한 유저 발생시 자신을 제외한 접속한 유저 렌더링
useEffect(() => {
socket.emit("join", num.current);
socket.on("join", (data) => {
editUserList(data);
});
socket.on("left", (data) => {
editUserList(data);
});
}, [socket]);
동일한 부분인 setUserList를 useEffect의 밖으로 빼서 editUserList라는 함수로 선언하고 가져다 쓰는 방식으로 변경을 하였고, 불필요하게 2개로 선언한 useEffect도 하나로 합칠 수 있었다.
역시 면접은 많이 보면 볼 수록 좋다는 말을 깨닳음 많은 하루였다.