React聊天机器人:发送用户输入与获取AI响应时显示加载消息
React聊天机器人加载消息无法优先显示的解决方案
问题根源
你当前的实现逻辑是通过单独的aiIsLoading状态控制加载提示,且仅在渲染最后一条AI消息时显示加载文本,但这种方式没有将加载状态与消息列表强绑定,导致加载提示无法及时、正确地优先于AI响应出现。正确的做法应该是将加载状态作为一条特殊消息加入到消息数组中,让它同步出现在聊天流里,待AI响应返回后再替换这条加载消息。
修改后的代码实现
1. 更新消息发送逻辑(handleSendMessage)
const handleSendMessage = () => { console.log('handleSendMessage started'); if (inputMessage.trim() !== '') { const newMessage = { text: inputMessage, isUser: true, }; // 先添加用户消息 setMessages(prev => [...prev, newMessage]); // 立即添加加载消息 const loadingMessage = { isUser: false, isLoading: true, text: '' }; setMessages(prev => [...prev, loadingMessage]); fetch("http://localhost:8000/send_info", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ input: inputMessage }), }) .then((response) => response.json()) .then((data) => { console.log('handleSendMessage fetch success'); // 移除加载消息:过滤掉最后一条加载状态的消息 setMessages(prev => prev.filter(msg => !msg.isLoading)); if (data.just_gpt_result || typeof data.result === 'string' || typeof data.result === 'number' || data.result.chart_image_base64) { let chatbotResponses = []; if (data.just_gpt_result) { const responseText = typeof data.just_gpt_result === 'object' ? JSON.stringify(data.just_gpt_result) : data.just_gpt_result; chatbotResponses.push({ text: responseText, isUser: false }); } else if (typeof data.result === 'string') { try { const jsonData = JSON.parse(data.result); chatbotResponses.push({ component: <DataTable columns={jsonData.columns} data={jsonData.data} />, isUser: false, }); } catch (error) { console.error('Error parsing JSON:', error); chatbotResponses.push({ text: data.result, isUser: false }); } } else if (typeof data.result === 'number' && Number.isInteger(data.result)) { chatbotResponses.push({ text: data.result, isUser: false }); } else if (data.result.chart_image_base64) { chatbotResponses.push({ component: ( <img src={`data:image/png;base64,${data.result.chart_image_base64}`} alt="Chart Image" className="chart-image" style={{ maxWidth: '100%', height: 'auto' }} /> ), isUser: false, }); } else { console.log('Received unsupported data:', data.result); chatbotResponses.push({ text: data.result, isUser: false }); } // 添加所有AI响应消息 setMessages(prev => [...prev, ...chatbotResponses]); } }) .catch((error) => { console.error("Error sending user input:", error); // 移除加载消息,并添加错误提示 setMessages(prev => [ ...prev.filter(msg => !msg.isLoading), { text: '请求失败,请重试', isUser: false } ]); }); setInputMessage(''); } };
2. 更新聊天窗口渲染逻辑
<div className="chatbot-container"> {messages.map((message, index) => ( <div key={index} className={message.isUser ? "user-message" : "ai-message"}> {message.isUser ? ( // 渲染用户消息的原有逻辑 <span>{message.text}</span> ) : message.isLoading ? ( // 渲染加载消息 <LoadingMessage>Loading...</LoadingMessage> ) : ( // 渲染AI响应消息 <> {message.text && <span>{message.text}</span>} {message.component && message.component} </> )} </div> ))} </div>
关键改进点
- 加载状态不再依赖单独的
aiIsLoading变量,而是作为消息数组的一部分,确保加载提示能立即出现在聊天流中 - AI响应返回后,先移除加载消息再添加实际回复,保证聊天流的顺序正确
- 统一处理多种AI响应类型,避免多次调用
setMessages导致的状态更新混乱
内容的提问来源于stack exchange,提问作者Emmanuel Nyatefe
相关产品推荐
相关产品推荐

