From 9160b47343cd1fcdfca81a89e8ad74281a2c6ca0 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Fri, 16 Sep 2022 10:50:48 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E8=B0=83=E6=95=B4=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChatMessageList/VirtualizedList.tsx | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/client/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx b/client/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx index d93de4f1..fe4636d8 100644 --- a/client/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx +++ b/client/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx @@ -4,9 +4,9 @@ import type { MessageListProps } from './types'; import { FollowOutputScalarType, Virtuoso, - VirtuosoGridHandle, + VirtuosoHandle, } from 'react-virtuoso'; -import { ChatMessage, sharedEvent } from 'tailchat-shared'; +import { ChatMessage, sharedEvent, useMemoizedFn } from 'tailchat-shared'; import _last from 'lodash/last'; const PREPEND_OFFSET = 10 ** 7; @@ -21,7 +21,7 @@ const virtuosoStyle: React.CSSProperties = { */ export const VirtualizedMessageList: React.FC = React.memo( (props) => { - const listRef = useRef(); + const listRef = useRef(null); const numItemsPrepended = usePrependedMessagesCount(props.messages); useEffect(() => { @@ -40,7 +40,7 @@ export const VirtualizedMessageList: React.FC = React.memo( }; }, []); - const handleLoadMore = () => { + const handleLoadMore = useMemoizedFn(() => { if (props.isLoadingMore) { return; } @@ -48,31 +48,33 @@ export const VirtualizedMessageList: React.FC = React.memo( if (props.hasMoreMessage) { props.onLoadMore(); } - }; - - const followOutput = (isAtBottom: boolean): FollowOutputScalarType => { - if (isAtBottom) { - // 更新最新查看的消息id - const lastMessage = _last(props.messages); - if (lastMessage) { - props.onUpdateReadedMessage(lastMessage._id); + }); + + const followOutput = useMemoizedFn( + (isAtBottom: boolean): FollowOutputScalarType => { + if (isAtBottom) { + // 更新最新查看的消息id + const lastMessage = _last(props.messages); + if (lastMessage) { + props.onUpdateReadedMessage(lastMessage._id); + } + + setTimeout(() => { + // 这里 Virtuoso 有个动态渲染高度的bug, 因此需要异步再次滚动到底部以确保代码功能work + listRef.current?.scrollToIndex({ + index: + PREPEND_OFFSET - numItemsPrepended + props.messages.length - 1, + align: 'end', + }); + }, 20); } - setTimeout(() => { - // 这里 Virtuoso 有个动态渲染高度的bug, 因此需要异步再次滚动到底部以确保代码功能work - listRef.current?.scrollToIndex({ - index: - PREPEND_OFFSET - numItemsPrepended + props.messages.length - 1, - align: 'end', - }); - }, 20); + /** + * 如果有新的内容,且当前处于最底部时, 保持在最底部 + */ + return isAtBottom ? 'smooth' : false; } - - /** - * 如果有新的内容,且当前处于最底部时, 保持在最底部 - */ - return isAtBottom ? 'smooth' : false; - }; + ); const itemContent = (virtuosoIndex: number) => { const index = virtuosoIndex + numItemsPrepended - PREPEND_OFFSET; @@ -83,16 +85,17 @@ export const VirtualizedMessageList: React.FC = React.memo( return ( );