昨天我們做了「假AI回覆」,雖然有雙方互動,但AI回覆是瞬間出現的。真實的聊天體驗通常會有一個小小的「正在輸入」或「思考中」提示,今天我們就來加上這個細節。
我們要引入一個狀態loading,用來判斷AI是否正在思考。
// src/ChatBox.jsx
import { useState } from "react"
export default function ChatBox(){
const [messages, setMessages] = useState([])
const [input, setInput] = useState("")
const [loading, setLoading] = useState(false)
const sendMessage = () => {
if(input.trim() === "") return
const newMessages = [...messages, {role: "user", text: input}]
setMessages(newMessages)
setInput("")
// 顯示loading
setLoading(true)
// 模擬AI回覆
setTimeout(() => {
setMessages([
...newMessages,
{role: "ai", text: "這是AI的回覆:我收到了!"}
])
setLoading(false) // 回覆後隱藏loading
}, 1500) // 模擬1.5秒思考
}
return (
<div className="flex flex-col h-full">
{/* 聊天訊息區 */}
<div className="flex-1 overflow-y-auto space-y-3 p-4 bg-white rounded shadow">
{messages.map((msg, idx) => (
<div
key={idx}
className={`p-2 rounded max-w-xs ${
msg.role === "user"
? "bg-blue-100 ml-auto text-right"
: "bg-gray-200 mr-auto text-left"
}`}
>
{msg.text}
</div>
))}
{/* AI正在思考中... */}
{loading && (
<div className="italic text-gray-500 text-sm">
AI正在思考中...
</div>
)}
</div>
{/* 輸入框 */}
<div className="flex mt-4">
<input
value={input}
onChange={(e) => setInput(e.target.value)}
className="flex-1 border rounded-l px-3 py-2"
placeholder="輸入訊息..."
/>
<button
onClick={sendMessage}
className="bg-blue-600 text-white px-4 rounded-r hover:bg-blue-700"
>
送出
</button>
</div>
</div>
)
}