tencent cloud

即时通信 IM

动态与公告
产品动态
公告
产品简介
产品概述
基本概念
应用场景
功能介绍
账号系统
用户资料与关系链
消息管理
群组相关
公众号系统
音视频通话 Call
使用限制
购买指南
计费概述
价格说明
购买指引
续费指引
停服说明
退费说明
开发指引
Demo 专区
开通服务
体验 Demo
快速跑通
下载中心
SDK & Demo 源码
更新日志
聊天互动(含 UI)
TUIKit 组件介绍
快速开始
全功能接入
单功能接入
AI 集成
构建基础界面
更多特性
定义外观
国际化界面语言
推送服务(Push)
服务概述
名词解释
开通服务
快速跑通
厂商通道
数据统计
排查工具
客户端 API
服务端 API
推送回调
高级功能
更新日志
错误码
常见问题
智能客服
功能概述
快速入门
集成指引
管理员操作手册
客服操作手册
更多实践
直播间搭建
AI 聊天机器人方案
超大娱乐协作社群
Discord 实现指南
游戏内集成 Chat 指南
类 WhatsApp Channel 搭建方案
发送红包
Chat 应对防火墙限制相关
无 UI 集成
快速开始
集成 SDK
初始化
登录登出
消息相关
会话相关
群组相关
社群话题
用户管理
离线推送
云端搜索
本地搜索
公众号
客户端 API
JavaScript
Android
iOS & macOS
Swift
Flutter
Electron
Unity
React Native
C 接口
C++
服务端 API
生成 UserSig
REST API
第三方回调
控制台指南
新版控制台介绍
创建并升级应用
基本配置
功能配置
账号管理
群组管理
公众号管理
回调配置
用量统计
资源包查看指南
实时监控
开发辅助工具
访问管理
高级功能
常见问题
uni-app 常见问题
购买相关问题
SDK 相关问题
账号鉴权相关问题
用户资料与关系链相关问题
消息相关问题
群组相关问题
直播群相关问题
昵称头像相关问题
协议与认证
服务等级协议
安全合规认证
IM 政策
隐私政策
数据隐私和安全协议
平滑迁移方案
平滑迁移完整版
平滑迁移简化版
错误码
联系我们

MessageList State

PDF
聚焦模式
字号
最后更新时间: 2025-07-22 16:21:48

MessageListState 概述

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

什么时候需要 MessageListState?

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

属性列表

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

属性详细说明

messageList

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

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈