reactjs 更改用户输入的呈现顺序和聊天机器人回复

mec1mxoz  于 2023-03-08  发布在  React
关注(0)|答案(3)|浏览(138)

所以,我有这个聊天机器人,你可以问一个问题,机器人会分析这个问题,并相应地回复它。所以,用户只需要在输入栏中输入他/她想问的问题的文本,当他/她点击提交按钮或点击回车键,问题被推到对话数组,机器人基于所问的问题进行回复,并且机器人的回复也被添加到对话数组。然后Map会话数组,使得所有会话以类似于Facebook信使的方式呈现在聊天页面中;聊天机器人的回复在聊天页面的左侧,而用户提出的问题在聊天页面的右侧。(这是在Map会话数组时完成的,奇数索引上的所有聊天都是用户提问,偶数索引上的会话是机器人回复的会话)。但是,我现在面临的问题是,如果用户输入文本并非常快速地重复提交,对话数组的顺序就会混乱(例如,如果我以非常快的速度输入并点击submit/enter四次,我键入的所有4个对话被呈现为好像它是我和机器人之间的对话并且一旦机器人对我问的第一个问题有答复,它会在我连续发送4条短信后显示,甚至可能显示在聊天页面的右侧或左侧。我如何在react web app中解决这个问题?我尝试使用setTimeout,但它不起作用,或者我使用它的方式不正确?
下面是一些代码:

const SendChat = (e) => {
    e.preventDefault();

    // add text to show on conversation
    dispatch(pushToChatConvArray({ user_conv: UserConversation }));
    // Send API Call
    // setTimeout(() => dispatch(botConvrse({ id: parseInt(sessionId), utt_user: userUtter })), 5000);
    dispatch(botConvrse({ id: parseInt(sessionId), user_conv: UserConversation }));

    setUserConversation("");
  };

<div>
<form onSubmit={SendChat}>
          <input
            autoFocus
            className="user-chat-form"
            placeholder="What's on your mind?"
            onChange={(e) => setUserConversation(e.target.value)}
            value={UserConversation}
          ></input>
          <IconButton type="submit">
            <SendIcon />
          </IconButton>
        </form>
</div>
// the this content is displayed on the chatpage
let content = chatList.map((item, idx) =>
    idx % 2 == 0 ? (
      <motion.div
        key={`chat ${idx}`}
      >
        <ChatContainer userOrBot={idx % 2 === 0 ? 0 : 1} conversation={item} />
      </motion.div>
    ) : (
      <motion.div
        key={`chat ${idx}`}
      >
        <ChatContainer userOrBot={idx % 2 === 0 ? 0 : 1} conversation={item} />
      </motion.div>
    )

我试图解释主要的问题,并提供了该问题的一些基本代码

wh6knrhe

wh6knrhe1#

假设对话应该是上下文相关的(等待和响应之前发送的消息),一种方法是在聊天机器人思考时禁用表单。

<form onSubmit={SendChat}>
   <fieldset disabled={botThinking}>
   ... your form elements
   </fieldset>       
</form>

然后,可以在使用botConverse方法之前和之后使用useState设置botThinking
您可能还想在sendChat处理程序中添加一些内容:

if (botThinking) return;
gev0vcfq

gev0vcfq2#

是的,我知道你的问题是什么了。你可能把chatList作为react状态。这就是文本数组。

chatList - ["Hi", "How are you?", "I am fine" ...]

不如你把这个状态更新成

chatList - [{text: "Hi", from: "you"}, {text: "How are you?", from: "bot"}, {text: "I am fine", from: "you"}, ...]

通过这种方式,您可以轻松确定哪个是您的,哪个是机器人的。

s5a0g9ez

s5a0g9ez3#

***假设***对话像这样一对一轮流进行似乎很不安全。

我的建议是在处理聊天提交时阻止输入。
示例:

const [canChat, setCanChat] = React.useState(true);

const sendChat = async (e) => {
  e.preventDefault();

  try {
    setCanChat(false); // <-- block user chat input
    
    // add text to show on conversation
    dispatch(pushToChatConvArray({ user_conv: UserConversation }));
    
    // Send API Call
    await dispatch(botConvrse({
      id: parseInt(sessionId),
      user_conv: UserConversation
    }));
  } catch {
    // handle or ignore rejected Promises/thrown errors/etc
  } finally {
    setCanChat(true); // <-- enable user chat input
    setUserConversation("");
  }
};

...

<div>
  <form onSubmit={sendChat}>
    <input
      autoFocus
      disabled={!canChat} // <-- disable input element when user can't chat
      className="user-chat-form"
      placeholder="What's on your mind?"
      onChange={(e) => setUserConversation(e.target.value)}
      value={UserConversation}
    />
    <IconButton type="submit">
      <SendIcon />
    </IconButton>
  </form>
</div>

或者输入哪个用户是他们那部分对话的所有者。这部分对话在处理时可以设置为分派操作的一部分。
示例:

const sendChat = (e) => {
  e.preventDefault();

  // add text to show on conversation, sets user as owner
  dispatch(pushToChatConvArray({ user_conv: UserConversation }));

  // Send API Call, sets bot as owner
  dispatch(botConvrse({
    id: parseInt(sessionId),
    user_conv: UserConversation
  }));

  setUserConversation("");
};

...

// the this content is displayed on the chatpage
const content = chatList.map((conversation) => (
  <motion.div key={conversation.id}>
    <ChatContainer
      userOrBot={conversation.isUserOwner}
      conversation={conversation}
    />
  </motion.div>
));

相关问题