From 7b20edeacb9b62d6367989cd5db8cd2e606a785f Mon Sep 17 00:00:00 2001 From: syc0123 Date: Tue, 31 Mar 2026 16:17:30 +0900 Subject: [PATCH] =?UTF-8?q?[RAPID-fix]=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=A0=90=ED=94=84=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0:=20useEffect=20=E2=86=92=20useLayoutEffect=20(?= =?UTF-8?q?=ED=8E=98=EC=9D=B8=ED=8A=B8=20=EC=A0=84=20=EC=B2=98=EB=A6=AC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/messenger/ChatPanel.tsx | 23 +++++++++------------ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/frontend/components/messenger/ChatPanel.tsx b/frontend/components/messenger/ChatPanel.tsx index c3119ddc..df6ca66a 100644 --- a/frontend/components/messenger/ChatPanel.tsx +++ b/frontend/components/messenger/ChatPanel.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useEffect, useRef, useState } from "react"; +import React, { useEffect, useLayoutEffect, useRef, useState } from "react"; import { MessageSquare, Pencil, Check, X, ChevronsDown } from "lucide-react"; import { useMessages, useMarkAsRead, useUpdateRoom } from "@/hooks/useMessenger"; import { useAuth } from "@/hooks/useAuth"; @@ -36,21 +36,18 @@ export function ChatPanel({ room }: ChatPanelProps) { const lastMessageId = messages?.[messages.length - 1]?.id; - // Hide messages until scrolled to bottom (prevents visible jump on room open) - useEffect(() => { + // useLayoutEffect: fires before browser paint → hide + scroll synchronously + useLayoutEffect(() => { + const el = scrollRef.current; + if (!el) return; setScrollReady(false); - }, [selectedRoomId]); + el.scrollTop = el.scrollHeight; + // Reveal after scroll is applied + requestAnimationFrame(() => setScrollReady(true)); + }, [selectedRoomId, lastMessageId]); - // Scroll to bottom when messages load or room changes - // Two-pass: immediate rAF + 600ms delayed (for async image loads) + // Second pass: re-scroll after async images load useEffect(() => { - requestAnimationFrame(() => { - const el = scrollRef.current; - if (el) { - el.scrollTop = el.scrollHeight; - setScrollReady(true); - } - }); const t = setTimeout(() => { const el = scrollRef.current; if (el) el.scrollTop = el.scrollHeight;