Skip to main content Inicio Creadores ant-design x use-x-chat
use-x-chat Focus on explaining how to use the useXChat Hook, including custom Provider integration, message management, error handling, multi-conversation management, and more
Ir a la instalación Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/ant-design/x --skill use-x-chatEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
Explorador de archivos
4 archivos name use-x-chat version 2.9.0 description Focus on explaining how to use the useXChat Hook, including custom Provider integration, message management, error handling, multi-conversation management, and more
🎯 Skill Positioning
Core Positioning : Use the useXChat Hook to build professional AI conversation applications. Prerequisite : Already have a custom Chat Provider (refer to x-chat-provider skill )
Table of Contents
🚀 Quick Start
1. Dependency Management
@ant-design/x-sdk : 2.2.2+
@ant-design/x : latest version (UI components)
npm install @ant-design/x-sdk@latest @ant-design/x@latest
2. Three-step Integration
Step 1: Prepare Provider
Handled by the x-chat-provider skill. Note XRequest must pass manual: true:
import { MyChatProvider } from './MyChatProvider' ;
import { XRequest } from '@ant-design/x-sdk' ;
const provider = new MyChatProvider ({
request : XRequest ('https://your-api.com/chat' , { manual : true }),
});
Step 2: Basic Usage import { useXChat } from '@ant-design/x-sdk' ;
const ChatComponent = ( ) => {
const { messages, onRequest, isRequesting } = useXChat ({
provider,
requestPlaceholder : (_, { messages } ) => ({
content : 'Thinking...' ,
role : 'assistant' ,
}),
requestFallback : (_, { error, messageInfo } ) => {
if (error.name === 'AbortError' ) {
return { content : messageInfo?.message ?.content || 'Reply cancelled' , role : 'assistant' };
}
return { content : 'Network error, please try again later' , role : 'assistant' };
},
});
return (
<div >
{messages.map((msg) => (
<div key ={msg.id} >
{msg.message.role}: {msg.message.content}
</div >
))}
<button onClick ={() => onRequest({ query: 'Hello' })}>Send</button >
</div >
);
};
Step 3: UI Integration
⚠️ messages is MessageInfo<ChatMessage>[] and cannot be passed directly to Bubble.List. It must be mapped to { key, role, content, loading } format. Bubble.List uses the role prop (not roles) to configure role styles.
import { Bubble , Sender } from '@ant-design/x' ;
const ChatUI = ( ) => {
const { messages, onRequest, isRequesting, abort } = useXChat ({ provider });
return (
<div style ={{ height: 600 }}>
<Bubble.List
// ✅ Correct: use role (not roles )
role ={{
user: { placement: 'end ' },
assistant: { placement: 'start ' },
}}
items ={messages.map(({ id , message , status }) => ({
key: id,
role: message.role, // matches role config key
content: message.content, // message content
loading: status === 'loading', // loading animation
}))}
/>
<Sender
loading ={isRequesting}
onSubmit ={(content) => onRequest({ query: content })}
onCancel={abort}
/>
</div >
);
};
When ChatMessage is an object type (not string) When ChatMessage is a complex object (e.g., with content, attachments fields), use contentRender:
<Bubble .List
role={{
assistant : {
placement : 'start' ,
contentRender (content : MyMessage ) {
return (
<div >
<div > {content.content}</div >
{content.attachments?.map((a) => (
<FileCard key ={a.url} name ={a.name} />
))}
</div >
);
},
},
user : {
placement : 'end' ,
contentRender (content : MyMessage ) {
return content.content ;
},
},
}}
items={messages.map (({ id, message, status } ) => ({
key : id,
role : message.role ,
content : message,
loading : status === 'loading' ,
}))}
/>
🧩 Core Concepts
Data Model
⚠️ Important : messages type is MessageInfo<ChatMessage>[]; message content is in msg.message
interface MessageInfo <ChatMessage > {
id : number | string ;
message : ChatMessage ;
status : MessageStatus ;
extraInfo ?: AnyObject ;
}
type MessageStatus = 'local' | 'loading' | 'updating' | 'success' | 'error' | 'abort' ;
useXChat Configuration Options Option Type Description providerAbstractChatProvider<ChatMessage, Input, Output>Required , Provider instanceconversationKeystringConversation unique identifier, required for multi-conversation defaultMessagesDefaultMessageInfo[] | () => ... | async () => ...Default display messages, supports async loading requestPlaceholderChatMessage | (requestParams, { messages }) => ChatMessagePlaceholder message during request requestFallbackChatMessage | (requestParams, { error, errorInfo, messages, messageInfo }) => ChatMessage | Promise<ChatMessage>Fallback message on request failure/abort parser(message: ChatMessage) => BubbleMessage | BubbleMessage[]Convert ChatMessage to component-consumable format, supports one-to-many
requestFallback's messageInfo type is MessageInfo<ChatMessage>, the message being updated when the request fails. requestFallback handles both network errors (error) and user abort (error.name === 'AbortError').
useXChat Return Values Return Value Type Description messagesMessageInfo<ChatMessage>[]Message list; must be mapped before passing to Bubble.List parsedMessagesMessageInfo<ParsedMessage>[]Message list after parser transform (use this when parser is set) onRequest(params: Partial<Input>, opts?: { extraInfo: AnyObject }) => voidAdd message and trigger request isRequestingbooleanWhether request is in progress abort() => voidAbort current request setMessages(messages: Partial<MessageInfo<ChatMessage>>[]) => voidDirectly modify message list, no request triggered setMessage(id: string | number, info: Partial<MessageInfo<ChatMessage>>) => voidModify single message, no request triggered removeMessage(id: string | number) => booleanDelete a message, returns whether deletion was successful onReload(id: string | number, params: Partial<Input>, opts?: { extraInfo: AnyObject }) => voidRegenerate an AI reply queueRequest(conversationKey: string | symbol, params: Partial<Input>, opts?: { extraInfo: AnyObject }) => voidQueue request, sent after conversation initializes isDefaultMessagesRequestingbooleanWhether default messages are async loading
🔧 Core Function Details Core functionality reference: CORE.md
🗂️ Multi-conversation Management
useXConversations Hook useXConversations is a conversation list management Hook provided by @ant-design/x-sdk, used together with useXChat for multi-conversation:
import { useXConversations } from '@ant-design/x-sdk' ;
import type { ConversationData } from '@ant-design/x-sdk' ;
const {
conversations,
activeConversationKey,
setActiveConversationKey,
addConversation,
removeConversation,
setConversation,
getConversation,
setConversations,
getMessages,
} = useXConversations ({
defaultConversations : [
{ key : 'conv-1' , label : 'Conversation 1' },
{ key : 'conv-2' , label : 'Conversation 2' },
],
defaultActiveConversationKey : 'conv-1' ,
});
Multi-conversation Full Pattern import { useXChat, useXConversations } from '@ant-design/x-sdk' ;
import { OpenAIChatProvider , XRequest } from '@ant-design/x-sdk' ;
import { Bubble , Conversations , Sender } from '@ant-design/x' ;
import React , { useEffect, useRef } from 'react' ;
const providerCache = new Map <string , OpenAIChatProvider >();
function getProvider (key : string ): OpenAIChatProvider {
if (!providerCache.has (key)) {
providerCache.set (
key,
new OpenAIChatProvider ({
request : XRequest (BASE_URL , { manual : true , params : { model : 'gpt-4o' , stream : true } }),
}),
);
}
return providerCache.get (key)!;
}
const App = ( ) => {
const senderRef = useRef<any >(null );
const { conversations, activeConversationKey, setActiveConversationKey, addConversation } =
useXConversations ({
defaultConversations : [{ key : 'conv-1' , label : 'New Conversation' }],
defaultActiveConversationKey : 'conv-1' ,
});
const { messages, onRequest, isRequesting, abort, queueRequest } = useXChat ({
provider : getProvider (activeConversationKey),
conversationKey : activeConversationKey,
defaultMessages : async ({ conversationKey }) => {
return [];
},
requestFallback : (_, { error, messageInfo } ) => {
if (error.name === 'AbortError' ) {
return { content : messageInfo?.message ?.content || 'Cancelled' , role : 'assistant' };
}
return { content : 'Request failed' , role : 'assistant' };
},
});
useEffect (() => {
senderRef.current ?.clear ?.();
}, [activeConversationKey]);
const handleNewConversation = ( ) => {
const newKey = `conv-${Date .now()} ` ;
addConversation ({ key : newKey, label : `New Conversation ${conversations.length + 1 } ` });
setActiveConversationKey (newKey);
};
return (
<div style ={{ display: 'flex ', height: '100vh ' }}>
<Conversations
items ={conversations}
activeKey ={activeConversationKey}
onActiveChange ={setActiveConversationKey}
creation ={{ onClick: handleNewConversation }}
/>
<div style ={{ flex: 1 , display: 'flex ', flexDirection: 'column ' }}>
<Bubble.List
role ={{ assistant: { placement: 'start ' }, user: { placement: 'end ' } }}
items ={messages.map(({ id , message , status }) => ({
key: id,
role: message.role,
content: message.content,
loading: status === 'loading',
}))}
/>
<Sender
ref ={senderRef}
loading ={isRequesting}
onCancel ={abort}
onSubmit ={(val) => {
onRequest({ messages: [{ role: 'user', content: val }] });
}}
/>
);
};
queueRequest: Delayed Send After Conversation Switch
const handleNewConversationWithFirstMessage = ( ) => {
const newKey = `conv-${Date .now()} ` ;
addConversation ({ key : newKey, label : 'New Conversation' });
setActiveConversationKey (newKey);
queueRequest (newKey, {
messages : [{ role : 'user' , content : 'Hello! Please introduce yourself.' }],
});
};
📋 Prerequisites and Dependencies Usage Scenario Required Skill/Provider Order Private API Adaptation x-chat-provider → use-x-chat Create Provider first Standard API Built-in Provider + use-x-chat Direct use Multi-conversation Provider factory + useXConversations + useXChat Use together
🚨 Development Rules Before using use-x-chat, confirm:
Test Case Rules
If the user does not explicitly need test cases, do not add test files
Code Quality Rules
After completion, must check types : Run tsc --noEmit to ensure no type errors
Keep code clean : Remove all unused variables and imports
🔗 Reference Resources
📚 Core Reference Documentation
🌐 SDK Official Documentation
💻 Example Code </div >
</div >