채팅 목록 업데이트 기능 만들기
JAVASCRIPT ·이전에 소켓의 연결을 통해, 새로운 채팅이 소켓에 들어오는 상황이 발생하면 그 메세지를 저장하는 기능을 만들었습니다. 이후 메세지 목록 내에서도 업데이트가 되는 상황이 발생하면, 이 사항을 바로 반영하는 기능을 넣어야 했습니다.
해당 기능을 만들기 위해서 거쳐야 하는 단계는 다음과 같았습니다.
- 새로운 채팅이 들어오면 채팅의 정보를 바로 가져오기(
id
,contents
) - 새로운 채팅의 정보와 일치하는 채팅 찾기
- 해당 채팅 업데이트 하기
- 업데이트 된 정보 처리하기
새로운 채팅의 정보 가져오기
export type ChatroomsUpdate = {
id?: number;
contents?: string;
};
export const chatroomsUpdateState = atom<ChatroomsUpdate>({
key: "chatroomsUpdate",
default: {},
});
// ChatroomsItem.tsx
const { id: updateId, contents: updateContents } =
useRecoilValue(chatroomsUpdateState);
현재 사용 중인 Recoil의 특성상, 특정 상태의 업데이트가 이루어지게 되면 해당 상태를 쓰는 곳에서도 업데이트가 이루어지기 때문에 해당 값을 가져오는 것만으로 업데이트가 가능했습니다.
일치하는 채팅 찾기 및 업데이트
// ChatroomsItem.tsx
const [curUnreadCount, setCurUnreadCount] = useState(unreadCount);
const [curRecentMessage, setCurRecentMessage] = useState<string | undefined>(
recentMessage
);
useEffect(() => {
if (chatRoomMemberId !== updateId) return;
setCurRecentMessage(updateContents);
setCurUnreadCount((prev) => prev + 1);
}, [updateContents]);
이후 useEffect
를 통해 updateContents
가 변하는 경우마다 특정 상황이 이루어지도록 했습니다. 여기서 id
값이 일치하는 경우에만 다음 작업이 이루어질 수 있도록 했으며, 이를 통해 해당 id
를 찾는 작업을 진행했습니다.
id
가 일치하는 경우, 해당 항목의 메세지를 새롭게 설정된 메세지(setCurRecentMessage
)로 바꾸고, 읽지 않은 개수(setCurUnreadCount
)도 증가하도록 설정했습니다.
업데이트된 정보 처리하기
하지만, 이렇게 설정할 경우, 한 가지 문제가 발생하게 됐는데, updateContents
라는 정보가 다른 페이지에 있다가 넘어오는 경우 useEffect
의 특성으로 인해 렌더링 후 바로 해당 id의 정보가 업데이트되어 버린다는 것입니다. 즉, 읽지 않은 항목이 1개씩 늘어나게 됩니다.
이 부분을 해결하기 위해서 두 가지 중 하나를 골라야했습니다.
- 업데이트가 이루어질 때마다
updateContents
를 초기화하기 updateContents
를 특정 타이밍에 초기화하기
첫 번째 경우의 수를 사용할 경우, 초기화를 하는 중간에 새로운 정보가 socket을 통해 들어오게 되면 제대로 된 데이터 처리가 되지 않을 가능성이 존재합니다. 이로 인해 updateContents
를 일정 시점에 초기화해주어야 하는데, 그 시점을 ‘채팅 목록 페이지를 나가는 시점’으로 했습니다. 이를 구현하기 위해 현재 페이지 내의 useEffect
에 리턴 함수를 적용해주었습니다.
// Chatrooms.tsx
useEffect(() => {
return () => setChatroomsUpdate({});
}, []);

🔎 여기서 현재 의문점이 드는 것은, 업데이트가 발생할 때마다 모든 채팅 한 번씩 검사는 거친다는 점에서, 렌더링에는 큰 무리가 없지만 계산이 계속 적용된다는 것에 문제가 있지는 않을까하는 생각이 들었고, 추후에 이것 외에 다른 방식으로 id
값을 비교할 방법이 있는지 알아보고자 합니다.