1- import { useCallback , useEffect , useRef } from "react"
1+ import { useEffect , useRef } from "react"
2+ import { Virtuoso , VirtuosoHandle } from "react-virtuoso"
23
34import { useChatUI } from "./useChatUI"
45import { ChatMessage } from "./ChatMessage"
56
67export function ChatMessages ( ) {
78 const { messages, isLoading, append } = useChatUI ( )
8- const containerRef = useRef < HTMLDivElement > ( null )
99 const messageCount = messages . length
10+ const virtuoso = useRef < VirtuosoHandle > ( null )
1011
11- const scrollToBottom = useCallback ( ( ) => {
12- if ( ! containerRef . current ) {
12+ useEffect ( ( ) => {
13+ if ( ! virtuoso . current ) {
1314 return
1415 }
1516
16- requestAnimationFrame ( ( ) => {
17- containerRef . current ?. scrollTo ( {
18- top : containerRef . current . scrollHeight ,
19- behavior : "smooth" ,
20- } )
21- } )
22- } , [ ] )
23-
24- useEffect ( ( ) => scrollToBottom ( ) , [ messageCount , scrollToBottom ] )
17+ requestAnimationFrame ( ( ) =>
18+ virtuoso . current ?. scrollToIndex ( { index : messageCount - 1 , align : "end" , behavior : "smooth" } ) ,
19+ )
20+ } , [ messageCount ] )
2521
2622 return (
27- < div ref = { containerRef } className = "flex flex-col flex-1 min-h-0 overflow-auto relative" >
28- { messages . map ( ( message , index ) => (
23+ < Virtuoso
24+ ref = { virtuoso }
25+ data = { messages }
26+ totalCount = { messageCount }
27+ itemContent = { ( index , message ) => (
2928 < ChatMessage
3029 key = { index }
3130 message = { message }
@@ -36,7 +35,7 @@ export function ChatMessages() {
3635 isLoading = { isLoading }
3736 append = { append }
3837 />
39- ) ) }
40- </ div >
38+ ) }
39+ / >
4140 )
4241}
0 commit comments