您可以在同一函数中多次调用同一useState挂钩吗?

时间:2020-01-23 04:47:37

标签: reactjs dialogflow-es react-hooks chatbot use-state

因此,在重构基于类的聊天机器人组件以使用react挂钩的过程中,我遇到了useState挂钩覆盖状态中的对象的问题。这只会导致漫游器响应显示在UI中。当我与漫游器聊天时,用户输入的闪烁会在UI中显示,然后会被chatbots的响应覆盖。这是代码:


export const Chatbot = () => {
  const [messages, setMessages] = useState([]);
  const [value, setValue] = useState("");

  async function df_text_query(text) {
    let says = {
      speaks: "me",
      message: {
        text: {
          text
        }
      }
    };
    setMessages([...messages, says]);

    const res = await axios.post("/api/df_text_query", {
      text,
      userID: cookies.get("userID")
    });

    // Handles fullfillment routes for dialogflow
    res.data.fulfillmentMessages.forEach(message => {
      says = {
        speaks: "bot",
        message
      };
      setMessages([...messages, says]);
    });
  }

  const handleChange = e => {
    setValue(e.target.value);
  };

  const handleSubmit = e => {
    e.preventDefault();
    if (value !== "") {
      const message = value.split();
      df_text_query(message);
    }
    setValue("");
  };

  const handleButtonSend = async event => {
    const eventText = event.target.innerText;
    await setValue(eventText);
    const message = value.split();
    await df_text_query(message);
    await setValue("");
  };

  return (
    <div>
      <div>chatbot code here</div>
    </div>
  );
};

是否可以在相同的异步函数中两次编写useState? 如果没有,我建议如何重构此代码,以便消息状态返回一个交替对象数组,例如:

[{says: {
   speaks: "me",
   message: {
       text: {
          text
       }
    }
  }
},
{says: {
   speaks: "bot",
   message: {
      text: {
        text
      }
     }
   }
 },
{says: {
   speaks: "me",
   message: {
       text: {
          text
       }
    }
  }
},
{says: {
   speaks: "bot",
   message: {
      text: {
        text
      }
     }
   }
 }
]```

Any answer would be very much appreciated. I've been stuck on this problem for a while now. If you need more information I'm happy to provide!

Cheers,

Jacks


1 个答案:

答案 0 :(得分:1)

尝试这样的事情:

 async function df_text_query(text) {
    let says = [{
      speaks: "me",
      message: {
        text: {
          text
        }
      }
    }];

    const res = await axios.post("/api/df_text_query", {
      text,
      userID: cookies.get("userID")
    });

    // Handles fullfillment routes for dialogflow
    let saysBatch = [says, ...res.data.fulfillmentMessages.map(message => ({
        speaks: "bot",
        message
      }))];
    setMessages([...messages, ...saysBatch]);