我正在尝试学习React,并使用OpenAI API构建一个简单但专业的聊天机器人。我目前能够发送和接收消息,但在显示消息时遇到了一个问题。当我发送用户消息时,用户消息将显示在页面上,但只有在响应到达时,用户消息才会消失。
我的Chat组件如下所示。我的猜测是setMessages([...messages, botMessage]);
只是在当前消息列表的状态后面附加了一条消息,尽管我可能误解了其中的一些内容。
import React, { useState } from "react";
import { PaperAirplaneIcon } from "@heroicons/react/20/solid";
import axios from "axios";
import UserMessage from "./UserMessage";
import BotMessage from "./BotMessage";
const Chat = () => {
const [messages, setMessages] = useState([]);
const [inputValue, setInputValue] = useState("");
const [loading, setLoading] = useState(false);
const [rules, setRules] = useState([]);
const handleInputSubmit = async (e) => {
e.preventDefault();
setLoading(true);
const userMessage = { type: "user", text: inputValue };
setMessages([...messages, userMessage]);
setInputValue("");
const botMessage = await getBotMessage(inputValue);
setMessages([...messages, botMessage]);
setLoading(false);
};
const getBotMessage = async (userMessage) => {
try {
const response = await axios.post("http://<url>/api/chat", {
message: userMessage,
});
console.log("response", response.data);
const botMessage = { type: "bot", text: response.data.response };
return botMessage;
} catch (e) {
console.log(e);
const botMessage = {
type: "bot",
text: "Something went wrong. Try again.",
};
return botMessage;
}
};
return (
<div className="flex flex-col items-center w-full h-full justify-between">
<h1 className="text-3xl font-bold my-5">Chatbot</h1>
<div className="w-full">
{messages.map((message, index) => {
if (message.type === "user") {
return <UserMessage key={index} text={message.text} />;
}
return <BotMessage key={index} text={message.text} />;
})}
<form
onSubmit={handleInputSubmit}
className="flex flex-row w-full mb-5 mt-2"
>
<input
className="border-2 rounded-md p-2 w-full"
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<button type="submit">
<PaperAirplaneIcon className="w-6 h-6 text-green-500" />
</button>
</form>
</div>
</div>
);
};
export default Chat;
2条答案
按热度按时间yqhsw0fo1#
你可以在这里的官方文档中找到解释:
set函数只为下一次渲染更新状态变量。如果你在调用set函数后读取状态变量,你仍然会得到调用前屏幕上的旧值。
调用
setMessages
不会导致message
变量立即更新。如果你仔细想想,这是完全有意义的,因为messages
被定义为const
,所以它永远不能被重新分配!在下一次重新渲染时,你将拥有一个新的messages
,其值已更新。因此,对
setMessages
的第二次调用是将botMessage
添加到原始数组中,有效地替换了userMessage
。您可以尝试使用更新器函数,如:
Updater函数也会在下一次重新渲染时执行,但它们是在队列中应用的,并且总是接收状态变量的最新值,因此这两个元素都将被正确添加。
velaa5lx2#
编辑:下面的解决方案可以,但不是最优方案,请查看其他答案。
作为React的新手,我不明白为什么会这样,但我找到了答案。
由于某种原因,
setMessages([...messages, botMessage]);
无法看到setMessages([...messages, userMessage]);
在三行之前(当发送用户消息时)给出的更新后的messages
状态数组。解决方案是添加这两条消息,当bot消息到达时,如,因此
handleInputSubmit
变为:如果有人能解释或提供一个链接到文档解释这一点,我将非常感谢。