帮你快速理解、总结文档立即下载

React

最近更新时间:2026-08-25 16:13:13
我的收藏

组件概述

Search 是一个功能完整的搜索解决方案,包含了搜索框、搜索结果展示、高级搜索等功能的完整组件集合。适用于即时通信、在线会议、在线教育等场景的用户、群组、消息搜索。
说明:
此功能属于增值服务,需要您购买云端搜索插件,请点击 购买
图片仅为效果示意
图片仅为效果示意


搜索模式

迷你模式
标准模式
嵌入式模式
适用于侧边栏或小容器
显示有限结果数量
支持展开查看更多
适用于全屏搜索界面
完整功能展示
支持高级搜索
适用于聊天界面
专注消息搜索
优化的布局
图片仅为效果示意
图片仅为效果示意

图片仅为效果示意
图片仅为效果示意

图片仅为效果示意
图片仅为效果示意


Props

属性名
类型
默认值
说明
variant
VariantType
VariantType.MINI
搜索模式:mini(迷你)、standard(标准)、embedded(嵌入式)。
className
string
-
自定义样式类名。
style
React.CSSProperties
-
自定义样式。
onKeywordChange
(keyword: string) => void
-
搜索关键词变化回调。
onResultItemClick
(result: object) => void
-
搜索结果点击回调。

基础使用

import { Search, VariantType } from '@tencentcloud/chat-uikit-react';

function App() {
return (
<Search variant={VariantType.MINI} />
);
}

SearchStore

SearchStore 提供了基于云端搜索的搜索能力。如果自定义组件能力不能支持您的业务,可以使用 SearchStore 实现您的需求。

属性

属性名
类型
说明
userList
UserProfile[]
用户搜索结果列表。
userTotalCount
number
用户搜索结果总数。
hasMoreUsers
boolean
用户搜索结果是否还有下一页。
groupList
GroupSearchInfo[]
群组搜索结果列表。
groupTotalCount
number
群组搜索结果总数。
hasMoreGroups
boolean
群组搜索结果是否还有下一页。
groupMemberList
Record<string, GroupMember[]>
群成员搜索结果,按 groupID 分组。
groupMemberTotalCount
number
群成员搜索结果总数。
hasMoreGroupMembers
boolean
群成员搜索结果是否还有下一页。
messageResults
MessageSearchResultItem[]
消息搜索结果列表。每项按会话聚合,包含会话 ID、会话展示信息、命中消息数量和消息列表。
messageResultTotalCount
number
消息搜索结果总数。
hasMoreMessageResults
boolean
消息搜索结果是否还有下一页。

方法

方法名
类型
说明
search
(keywordList: string[], option?: SearchOption) => Promise<void>
发起搜索。默认会同时搜索用户、群组、群成员和消息;可通过 option.searchScope 限制搜索范围。调用时会重置当前结果和分页游标。
searchMore
(searchType: SearchType) => Promise<void>
加载指定搜索类型的下一页结果。searchType 可为 User、Group、GroupMember、Message。
destroy
() => void
销毁当前 SearchStore 实例,清理订阅和状态。通常由 React/Vue3 封装层自动管理。
SearchOption
字段名
类型
说明
keywordListMatchMode
KeywordListMatchMode
多关键词匹配模式:Or 或 And。默认 Or。
searchScope
SearchType[]
搜索范围。默认包含用户、群组、群成员、消息四类。
pageSize
number
每页数量,默认 20。
userFilter
UserSearchFilter
用户搜索过滤条件。
messageFilter
MessageSearchFilter
消息搜索过滤条件。
groupMemberFilter
GroupMemberSearchFilter
群成员搜索过滤条件。

使用示例

index.tsx
index.css
import { useState } from 'react';
import {
SearchType,
SearchStore,
} from '@tencentcloud/chat-uikit-react';
import './styles.css';

function SearchStoreBasicDemo() {
const {
hasMoreUsers,
search,
searchMore,
userList,
userTotalCount,
} = SearchStore.create();

const [keyword, setKeyword] = useState('');
const [hasSearched, setHasSearched] = useState(false);
const [isLoading, setIsLoading] = useState(false);

const handleSearch = async () => {
const nextKeyword = keyword.trim();
if (!nextKeyword) {
return;
}

setIsLoading(true);
setHasSearched(true);
try {
await search([nextKeyword], {
pageSize: 20,
searchScope: [SearchType.User],
});
} finally {
setIsLoading(false);
}
};

const handleLoadMore = async () => {
setIsLoading(true);
try {
await searchMore(SearchType.User);
} finally {
setIsLoading(false);
}
};

return (
<div className="search-store-basic-demo">
<div className="search-store-basic-demo__header">
<h2>Search Store Basic</h2>
<p>Very simple user search powered by SearchStore.</p>
</div>

<div className="search-store-basic-demo__toolbar">
<input
onChange={event => setKeyword(event.target.value)}
onKeyDown={event => {
if (event.key === 'Enter') {
handleSearch();
}
}}
placeholder="Enter user keyword"
value={keyword}
/>
<button disabled={isLoading || !keyword.trim()} onClick={handleSearch} type="button">
{isLoading ? 'Searching...' : 'Search'}
</button>
</div>

<div className="search-store-basic-demo__panel">
<h3>Users ({userTotalCount})</h3>
{userList.length > 0 ? (
<ul className="search-store-basic-demo__list">
{userList.map(user => (
<li className="search-store-basic-demo__item" key={user.userID}>
<span className="search-store-basic-demo__avatar">
{(user.nickname || user.userID).slice(0, 1).toUpperCase()}
</span>
<span>
<strong>{user.nickname || user.userID}</strong>
<small>{user.userID}</small>
</span>
</li>
))}
</ul>
) : (
<div className="search-store-basic-demo__empty">
{hasSearched ? 'No users found.' : 'Enter a keyword and search.'}
</div>
)}
</div>

{hasMoreUsers && (
<button
className="search-store-basic-demo__more"
disabled={isLoading}
onClick={handleLoadMore}
type="button"
>
Load More
</button>
)}
</div>
);
}
.search-store-basic-demo {
display: flex;
height: 100%;
flex-direction: column;
gap: 16px;
padding: 24px;
overflow: hidden;
}

.search-store-basic-demo__header h2 {
margin: 0 0 8px;
color: #111827;
font-size: 22px;
}

.search-store-basic-demo__header p {
margin: 0;
color: #6b7280;
font-size: 14px;
}

.search-store-basic-demo__toolbar {
display: flex;
gap: 8px;
}

.search-store-basic-demo__toolbar input {
width: 260px;
padding: 8px 10px;
border: 1px solid #d7dce5;
border-radius: 8px;
}

.search-store-basic-demo__toolbar button,
.search-store-basic-demo__more {
padding: 8px 12px;
border: 1px solid #667eea;
border-radius: 8px;
background: #667eea;
color: #fff;
cursor: pointer;
}

.search-store-basic-demo__toolbar button:disabled,
.search-store-basic-demo__more:disabled {
opacity: 0.6;
cursor: not-allowed;
}

.search-store-basic-demo__panel {
display: flex;
width: min(560px, 100%);
min-height: 0;
flex: 1;
flex-direction: column;
overflow: hidden;
border: 1px solid #edf0f5;
border-radius: 12px;
background: #fff;
}

.search-store-basic-demo__panel h3 {
margin: 0;
padding: 14px 16px;
border-bottom: 1px solid #edf0f5;
color: #111827;
font-size: 15px;
}

.search-store-basic-demo__list {
display: flex;
flex-direction: column;
gap: 8px;
margin: 0;
padding: 12px;
overflow: auto;
list-style: none;
}

.search-store-basic-demo__item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
border-radius: 10px;
background: #f9fafb;
}

.search-store-basic-demo__avatar {
display: inline-flex;
width: 32px;
height: 32px;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #eef2ff;
color: #4f46e5;
font-size: 13px;
font-weight: 700;
}

.search-store-basic-demo__item strong,
.search-store-basic-demo__item small {
display: block;
}

.search-store-basic-demo__item strong {
color: #111827;
font-size: 14px;
}

.search-store-basic-demo__item small {
margin-top: 2px;
color: #6b7280;
font-size: 12px;
}

.search-store-basic-demo__empty {
padding: 24px;
color: #6b7280;
text-align: center;
}

.search-store-basic-demo__more {
width: fit-content;
}

常见问题

Q:如何自定义搜索结果的显示格式?

A:搜索组件不支持自定义,可以使用 SearchStore 自主实现 Search 组件。