MessageList State
MessageListState Overview
MessageListState is a status management center related to building message lists, specialized in managing message list status and operations. It provides core features like message list data management, load by page, read receipt settings, and scroll control, making it an important tool to build chat interface.MessageListState adopts a responsive design, can automatically listen to underlying data changes and refresh component status, and provides various business operation methods to satisfy different use cases.When to Use MessageListState
When the current MessageList capacity cannot meet the requirement, or if you want to redevelop MessageList with the aid of underlying data, you can use
useMessageListState() to obtain the original data source and perform redevelopment.List of attributes
Field | Type | Description |
messageList | readonly MessageModel[] | undefined | Message list data |
hasMoreOlderMessage | boolean | undefined | Whether more historical messages can be loaded |
enableReadReceipt | boolean | undefined | Whether to enable the receipt feature |
isDisableScroll | boolean | Disable scrolling |
setIsDisableScroll | (isDisableScroll: boolean) => void | Method to set the scroll state |
loadMoreMessage | () => Promise<any> | Method to load more messages |
setEnableReadReceipt | (enableReadReceipt: boolean | undefined) => void | Method to set the read receipt status |
Attribute Details
messageList
Type:
readonly MessageModel[] | undefinedDescription: The message list data of the current session. This is a read-only array containing all loaded message objects. Each message object contains complete information such as message content, sender, timestamp, and status. When the underlying data is not fully loaded, the value is
undefined.hasMoreOlderMessage
Type:
boolean | undefinedDescription: Indicates whether there are more historical messages to load. When the value is
true, it means earlier messages can be obtained through the loadMoreMessage method; when the value is false, it means all historical messages have already been loaded; when the value is undefined, it means the loading status is undetermined.
enableReadReceipt
Type:
boolean | undefinedDescription: Control whether to enable the read receipt feature. When set to
true, the message will display read status; when set to false, it will not show read status; when the value is undefined, it means the user has not specified whether to enable the read receipt feature.isDisableScroll
Type:
booleanDescription: Control the scrolling behavior of the message list. When set to
true, it disables the auto-scroll feature; when set to false, it allows normal scrolling. Typically set to true when users manually scroll through historical messages to avoid auto-scroll affecting user experience upon new message arrival. This field setting does not disable page scroll. Please use this field for control on the dom side.setIsDisableScroll
Type:
(isDisableScroll: boolean) => voidDescription: Method used to set scroll status. Receives a boolean parameter to control whether to disable scroll functionality.
loadMoreMessage
Type:
() => Promise<any>Description: Method to asynchronously load more historical messages. Calling this method sends a server request for earlier message data and auto-updates the
messageList and hasMoreOlderMessage status.setEnableReadReceipt
Type:
(enableReadReceipt: boolean | undefined) => voidDescription: Method used to set the receipt feature switch. It accepts a boolean value or
undefined parameter to control whether to enable read receipt.Usage Examples
Here is a complete MessageList component example that shows how to use
messageList, hasMoreOlderMessage, and loadMoreMessage to build a message list with pagination loading:import React, { useEffect, useRef, useState } from 'react';import { useMessageListState } from '@tencentcloud/chat-uikit-react';import type { MessageModel } from '@tencentcloud/chat-uikit-react';import './MessageList.scss';interface MessageListProps {className?: string;}const MessageList: React.FC<MessageListProps> = ({ className }) => {const {messageList,hasMoreOlderMessage,loadMoreMessage,isDisableScroll,setIsDisableScroll,} = useMessageListState();const [isLoading, setIsLoading] = useState(false);const messageListRef = useRef<HTMLDivElement>(null);const prevScrollHeight = useRef<number>(0);// load more messagesconst handleLoadMore = async () => {if (isLoading || !hasMoreOlderMessage) return;setIsLoading(true);try {// Record the current scroll heightif (messageListRef.current) {prevScrollHeight.current = messageListRef.current.scrollHeight;}await loadMoreMessage();} catch (error) {console.error('Failed to load more messages:', error);} finally {setIsLoading(false);}};// Handle scroll eventconst handleScroll = (e: React.UIEvent<HTMLDivElement>) => {const target = e.target as HTMLDivElement;const { scrollTop, scrollHeight, clientHeight } = target;// Detect whether scrolled to top, trigger loading moreif (scrollTop === 0 && hasMoreOlderMessage && !isLoading) {handleLoadMore();}// detect whether users are viewing historical messageconst isAtBottom = scrollTop + clientHeight >= scrollHeight - 10;setIsDisableScroll(!isAtBottom);};// Keep scroll position (after loading more messages)useEffect(() => {if (messageListRef.current && prevScrollHeight.current > 0) {const newScrollHeight = messageListRef.current.scrollHeight;const scrollDiff = newScrollHeight - prevScrollHeight.current;messageListRef.current.scrollTop = scrollDiff;prevScrollHeight.current = 0;}}, [messageList]);// Auto-scroll to bottom (on message arrival)useEffect(() => {if (messageListRef.current && !isDisableScroll) {messageListRef.current.scrollTop = messageListRef.current.scrollHeight;}}, [messageList, isDisableScroll]);// Render a single messageconst renderMessage = (message: MessageModel) => (<div key={message.ID} className="message-item"><div className="message-sender">{message.nick || message.from}</div><div className="message-content">{(() => {if (message.type === 'TIMTextElem') {return <span className="text-message">{message.payload.text}</span>;} else {return <span>other message</span>;}})()}</div><div className="message-time">{new Date(message.time * 1000).toLocaleTimeString()}</div></div>);return (<div className={`im-message-list-container ${className || ''}`}>{/* load more indicator */}{hasMoreOlderMessage && (<div className="load-more-indicator">{isLoading ? (<div className="loading">loading...</div>) : (<button onClick={handleLoadMore} className="load-more-btn">load more messages</button>)}</div>)}{/* message list */}<divref={messageListRef}className="message-list"onScroll={handleScroll}>{messageList?.map(renderMessage)}</div>{/* empty state */}{messageList?.length === 0 && (<div className="empty-state">No Messages</div>)}</div>);};export default MessageList;
Style Reference
.im-message-list-container {display: flex;flex-direction: column;flex: 1 1 auto;overflow: auto hidden;.load-more-indicator {padding: 10px;text-align: center;border-bottom: 1px solid #eee;.loading {color: #666;font-size: 14px;}.load-more-btn {padding: 8px 16px;background: #007bff;color: white;border: none;border-radius: 4px;cursor: pointer;&:hover {background: #0056b3;}}}.message-list {flex: 1;overflow-y: auto;min-height: 0;padding: 10px;.message-item {margin-bottom: 15px;padding: 10px;background: #f5f5f5;border-radius: 8px;.message-sender {font-weight: bold;color: #333;margin-bottom: 5px;}.message-content {color: #666;line-height: 1.5;margin-bottom: 5px;}.message-time {font-size: 12px;color: #999;text-align: right;}}}.empty-state {flex: 1;display: flex;align-items: center;justify-content: center;color: #999;font-size: 14px;}}
This example shows how to:
1. Use
messageList to render the message list.2. Determine whether to display the load more button via
hasMoreOlderMessage.3. Call
loadMoreMessage to load by page.4. Combine
isDisableScroll and setIsDisableScroll to optimize scrolling experience.5. Handle loading and empty state display.