Supabase 실시간 데이터 타입 불일치 문제
- 문제: payload.new의 타입이 Message와 맞지 않아 TypeScript 에러 발생.
- 원인: Supabase의 실시간 이벤트에서 반환된 데이터(payload.new)는 기본적으로 any 타입으로 처리되며, 정의된 Message 타입과 불일치.
- Supabase에서 반환된 데이터 타입을 명시적으로 캐스팅해줌.
const message = payload.new as Message;
Supabase-React 채팅 메시지 순서 문제 해결
- 문제: 채팅 모달을 닫았다가 다시 열면 메시지 순서가 뒤섞임. Supabase에서 메시지를 가져오는 과정과 실시간 업데이트 로직에서 발생한 문제로 생각됨.
- 원인: fetchMessages 함수에서 Supabase 쿼리에 명시적인 order 조건이 빠져 있음. Supabase는 기본적으로 데이터를 삽입된 순서대로 반환하지 않을 수 있음. 또한 새 메시지가 추가될 때 기존 상태 배열에 단순히 추가만 되고 있어 기존에 잘못된 순서로 로드된 메시지와 섞일 가능성이 있음.
- 메시지를 가져올 때 created_at 기준으로 정렬 추가함.
const { data, error } = await supabase
.from('messages')
.select('*, users(*)')
.eq('chatroom_id', chatroomId)
.order('created_at', { ascending: true });
- 실시간 메시지가 추가될 때 기존 배열과 섞이지 않도록, 업데이트 시 정렬 로직 추가.
const channel = supabase
.channel(`messages:chatroom_id=eq.${chatroomId}`)
.on(
'postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'messages', filter: `chatroom_id=eq.${chatroomId}` },
(payload) => {
const newMessage = payload.new as Message;
setMessages((prev) =>
[...prev, newMessage].sort(
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
)
);
}
)
.subscribe();
채팅 스크롤 자동 최하단 이동
- 문제: 채팅 화면에서 새로운 메시지가 추가되거나, 컴포넌트가 처음 렌더링될 때 메시지 리스트가 자동으로 최하단으로 스크롤되지 않음. 사용자 경험 문제.
- useRef를 활용한 메시지 리스트 끝부분 참조 생성 (behavior 옵션에 따라 smooth, auto 등 스크롤 속도 변경 가능!)
const messageEndRef = useRef<HTMLDivElement | null>(null);
// ----- (중략) ----- //
useEffect(() => {
if (messageEndRef.current) {
messageEndRef.current.scrollIntoView({ behavior: 'smooth' });
}
}, [messages]); // messages가 변경될 때마다 실행
'스파르타코딩클럽 > 과제' 카테고리의 다른 글
[supabase realtime을 이용한 채팅 구현하기] 채팅 ui 모달 (0) | 2024.12.23 |
---|---|
[React 심화 주차] 팀 프로젝트_개발 멘토링 플랫폼 (1) | 2024.12.20 |
[Next.js/Typescript] LOL_Dex: NextJS에서 환경변수 사용하기 (0) | 2024.12.19 |
[Next.js/Typescript] LOL_Dex: 컴포넌트에서 버전 정보 전달하기 (0) | 2024.12.19 |
메인페이지, 레이아웃 구성 (2) | 2024.12.18 |