MessageList State

最近更新时间:2025-09-12 18:14:53

我的收藏

MessageListState 概述

MessageListState 是一个与消息列表构建相关的状态管理中心,专门用于管理消息列表的状态和操作。它提供了消息列表的数据管理、分页加载、阅读回执设置、滚动控制等核心功能,是构建聊天界面的重要工具。
MessageListState 采用了响应式设计,能够自动监听底层数据变化并更新组件状态,同时提供了丰富的业务操作方法来满足不同的使用场景。

什么时候使用 MessageListState?

当目前的 MessageList 组件能力无法满足需求,或者希望借助底层数据重新开发 MessageList 时,可以使用 useMessageListState() 获取原始的数据源并进行重新开发。

属性列表

字段
类型
描述
readonly IMessageModel[] | undefined
消息列表数据
boolean | undefined
是否还有更多历史消息可加载
boolean | undefined
是否启用阅读回执功能
boolean
是否禁用滚动
(isDisableScroll: boolean) => void
设置滚动状态的方法
() => Promise<any>
加载更多消息的方法
(enableReadReceipt: boolean | undefined) => void
设置阅读回执状态的方法

属性详细说明

messageList

类型:readonly MessageModel[] | undefined
描述:当前会话的消息列表数据。这是一个只读数组,包含了所有已加载的消息对象。每个消息对象包含消息内容、发送者信息、时间戳、状态等完整信息。当底层数据未加载完毕时,该值为 undefined

hasMoreOlderMessage

类型:boolean | undefined
描述:标识是否还有更多的历史消息可以加载。当值为 true 时,表示还有更早的消息可以通过 loadMoreMessage 方法获取;当值为 false 时,表示已经加载了所有历史消息;当值为 undefined 时,表示加载状态未确定。

enableReadReceipt

类型:boolean | undefined
描述:控制是否启用已读回执功能。当设置为 true 时,消息会显示已读状态;当设置为 false 时,不显示已读状态;当值为 undefined 时,表示用户未指定是否启用已读回执功能。

isDisableScroll

类型:boolean
描述:控制消息列表的滚动行为。当设置为 true 时,禁用自动滚动功能;当设置为 false 时,允许正常滚动。通常在用户手动滚动查看历史消息时设置为 true,避免新消息到达时自动滚动影响用户体验。该字段的设置不会禁用页面的滚动,请在 DOM 侧使用该字段控制。

setIsDisableScroll

类型:(isDisableScroll: boolean) => void
描述:用于设置滚动状态的方法。接收一个布尔值参数来控制是否禁用滚动功能。

loadMoreMessage

类型:() => Promise<any>
描述:异步加载更多历史消息的方法。调用该方法会向服务器请求更早的消息数据,并自动更新 messageListhasMoreOlderMessage 状态。

setEnableReadReceipt

类型:(enableReadReceipt: boolean | undefined) => void
描述:用于设置阅读回执功能开关的方法。接收一个布尔值或 undefined 参数来控制是否启用阅读回执。

使用示例

以下是一个完整的 MessageList 组件示例,展示了如何使用 messageListhasMoreOlderMessageloadMoreMessage 来构建一个具有分页加载功能的消息列表:
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);

// 加载更多消息
const handleLoadMore = async () => {
if (isLoading || !hasMoreOlderMessage) return;

setIsLoading(true);
try {
// 记录当前滚动高度
if (messageListRef.current) {
prevScrollHeight.current = messageListRef.current.scrollHeight;
}

await loadMoreMessage();
} catch (error) {
console.error('加载更多消息失败:', error);
} finally {
setIsLoading(false);
}
};

// 处理滚动事件
const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
const target = e.target as HTMLDivElement;
const { scrollTop, scrollHeight, clientHeight } = target;

// 检测是否滚动到顶部,触发加载更多
if (scrollTop === 0 && hasMoreOlderMessage && !isLoading) {
handleLoadMore();
}

// 检测用户是否在查看历史消息
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 10;
setIsDisableScroll(!isAtBottom);
};

// 保持滚动位置(加载更多消息后)
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]);

// 自动滚动到底部(新消息到达时)
useEffect(() => {
if (messageListRef.current && !isDisableScroll) {
messageListRef.current.scrollTop = messageListRef.current.scrollHeight;
}
}, [messageList, isDisableScroll]);

// 渲染单条消息
const 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 || ''}`}>
{/* 加载更多指示器 */}
{hasMoreOlderMessage && (
<div className="load-more-indicator">
{isLoading ? (
<div className="loading">加载中...</div>
) : (
<button onClick={handleLoadMore} className="load-more-btn">
加载更多消息
</button>
)}
</div>
)}

{/* 消息列表 */}
<div
ref={messageListRef}
className="message-list"
onScroll={handleScroll}
>
{messageList?.map(renderMessage)}
</div>

{/* 空状态 */}
{messageList?.length === 0 && (
<div className="empty-state">
暂无消息
</div>
)}
</div>
);
};

export default MessageList;

样式参考

.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;
}
}
这个示例展示了如何:
使用 messageList 渲染消息列表。
通过 hasMoreOlderMessage 判断是否显示加载更多按钮。
调用 loadMoreMessage 实现分页加载。
结合 isDisableScrollsetIsDisableScroll 优化滚动体验。
处理加载状态和空状态的显示。

扩展资料

MessageModel 类型常用字段:
// MessageModel 接口定义,详细内容请参考 @tencentcloud/chat-uikit-engine 文档
// 这是一个复杂的消息模型,包含消息ID、类型、发送者、内容、时间、状态等属性。
// 示例结构 (非完整定义):
interface MessageModel {
ID: string;
conversationID: string;
type: MessageType;
payload: any;
flow: 'in' | 'out';
from: string;
to: string;
time: number; // Unix 时间戳 (秒)
status: 'unSend' | 'success' | 'fail';
isDeleted: boolean;
isRevoked: boolean;
hasRiskContent: boolean; // 是否包含风险内容
// ... 其他属性
}

MessageModel 的完整内容请参考:TUIChatEngine 参考文档

相关文档

交流与反馈

如遇任何问题,可联系 官网售后 反馈,享有专业工程师的支持,解决您的难题。