使用 React 实现 AI 对话窗口的核心逻辑,主要围绕对话状态管理、用户输入交互、AI 响应模拟/对接和UI 渲染四个部分展开。以下是具体实现思路和代码示例:
角色(用户/AI)、内容、状态(加载中/完成)等信息。
import { useState, useRef, useEffect } from 'react';
const AIChatWindow = () => {
// 对话记录:[{ role: 'user' | 'ai', content: string, loading: boolean }]
const [messages, setMessages] = useState([
{ role: 'ai', content: '你好!有什么可以帮你的吗?', loading: false }
]);
const [input, setInput] = useState('');
const chatEndRef = useRef(null); // 用于自动滚动到最新消息
// 自动滚动到最新消息
useEffect(() => {
chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
// 模拟AI响应(实际项目中替换为接口请求)
const getAIResponse = (userInput) => {
// 简单模拟不同问题的回答
const replies = {
'你好': '你好呀!😊',
'什么是React': 'React是一个用于构建用户界面的JavaScript库...',
'默认回复': '我正在学习中,这个问题我还不太清楚呢~'
};
return replies[userInput] || replies['默认回复'];
};
// 发送消息
const handleSend = async () => {
if (!input.trim()) return; // 空消息不发送
// 1. 添加用户消息到对话
const userMessage = { role: 'user', content: input, loading: false };
setMessages(prev => [...prev, userMessage]);
setInput(''); // 清空输入框
// 2. 添加AI"正在输入"状态
setMessages(prev => [...prev, { role: 'ai', content: '', loading: true }]);
// 3. 模拟AI思考延迟(实际项目中这里调用API)
setTimeout(() => {
const aiResponse = getAIResponse(input.trim());
// 更新AI消息(替换"正在输入"状态)
setMessages(prev => {
const newMessages = [...prev];
newMessages.pop(); // 移除"正在输入"
newMessages.push({ role: 'ai', content: aiResponse, loading: false });
return newMessages;
});
}, 1000); // 模拟1秒思考时间
};
return (
<div style={styles.container}>
<div style={styles.chatBox}>
{/* 对话列表 */}
{messages.map((msg, index) => (
<div
key={index}
style={msg.role === 'user' ? styles.userMsg : styles.aiMsg}
>
<span style={styles.roleLabel}>
{msg.role === 'user' ? '你' : 'AI'}
</span>
<div style={styles.content}>
{msg.loading ? '正在输入...' : msg.content}
</div>
</div>
))}
{/* 用于自动滚动的锚点 */}
<div ref={chatEndRef} />
</div>
{/* 输入区域 */}
<div style={styles.inputArea}>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
placeholder="输入消息..."
style={styles.input}
/>
<button onClick={handleSend} style={styles.sendBtn}>
发送
</button>
</div>
</div>
);
};
// 样式定义
const styles = {
container: {
width: 400,
height: 600,
border: '1px solid #ddd',
borderRadius: 8,
display: 'flex',
flexDirection: 'column',
margin: '20px auto'
},
chatBox: {
flex: 1,
padding: 16,
overflowY: 'auto',
backgroundColor: '#f9f9f9'
},
userMsg: {
textAlign: 'right',
marginBottom: 12
},
aiMsg: {
textAlign: 'left',
marginBottom: 12
},
roleLabel: {
fontSize: 12,
color: '#666',
marginBottom: 4,
display: 'inline-block'
},
content: {
maxWidth: '70%',
padding: 10,
borderRadius: 12,
display: 'inline-block'
},
userMsg: {
textAlign: 'right'
},
userMsg: {
'& $content': {
backgroundColor: '#0078d7',
color: 'white'
}
},
aiMsg: {
'& $content': {
backgroundColor: 'white',
border: '1px solid #ddd'
}
},
inputArea: {
display: 'flex',
padding: 12,
borderTop: '1px solid #ddd'
},
input: {
flex: 1,
padding: 8,
borderRadius: 4,
border: '1px solid #ddd',
outline: 'none'
},
sendBtn: {
marginLeft: 8,
padding: 8 16,
backgroundColor: '#0078d7',
color: 'white',
border: 'none',
borderRadius: 4,
cursor: 'pointer'
}
};
export default AIChatWindow;对接真实 AI 接口
将 getAIResponse 替换为接口请求(如使用 fetch 或 axios):
const getAIResponse = async (userInput) => {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${你的API密钥}`
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: userInput }]
})
});
const data = await response.json();
return data.choices[0].message.content;
};加载状态优化 可添加“打字机效果”,让 AI 回复逐字显示,增强真实感:
// 替换AI消息更新逻辑
const aiResponse = "AI的完整回复内容";
let currentIndex = 0;
const interval = setInterval(() => {
currentIndex++;
setMessages(prev => {
const newMessages = [...prev];
newMessages.pop();
newMessages.push({
role: 'ai',
content: aiResponse.slice(0, currentIndex),
loading: currentIndex < aiResponse.length
});
return newMessages;
});
if (currentIndex >= aiResponse.length) clearInterval(interval);
}, 50); // 每50ms显示一个字历史记录持久化
使用 localStorage 保存对话记录,刷新页面后恢复:
// 初始化时读取本地存储
useEffect(() => {
const savedMessages = localStorage.getItem('aiChatHistory');
if (savedMessages) setMessages(JSON.parse(savedMessages));
}, []);
// 对话更新时保存到本地存储
useEffect(() => {
localStorage.setItem('aiChatHistory', JSON.stringify(messages));
}, [messages]);核心逻辑围绕“状态管理”和“交互流程”:
根据需求可扩展为多轮对话、消息编辑、文件上传等功能。