So I am creating a clone of Google Gemini using React js and I am keeping a useState hook to keep the track of the chat history in the format that gemini API requires (array of objects where each object has one property saying is it user or model and other property is object with just one property, the text). The problem is that when I give it one input the hook stores 1 input then response then again same input and again the same response whereas it should store only 1 input and 1 response.
The function’s code is :
const handleRun = async () => {
setCall((prev) => prev + 1);
console.log(call);
if (input !== "") {
console.log(conversationHistory);
const response = await run(conversationHistory, input);
setConversationHistory((prevHistory) => [
...prevHistory,
{ role: "user", parts: [{ text: input }] },
{ role: "model", parts: [{ text: response }] },
]);
console.log(conversationHistory);
setInput("");
}
};
2
Answers
It appears that your issue lies in the react hook’s asynchronous nature.
When you call
setConversationHistory
, even though it may seem like it would immediately updateconversationHistory
, it doesn’t. The state update is enqueued by React and happens at some later time, which can lead to unexpected results when you’re trying to examine the state immediately after calling the update function (setConversationHistory
in your case).You’re logging
console.log(conversationHistory)
right after updating the state, at a time when the state might not have been updated yet, which is why you’re not seeing the expected output.React guarantees the
prevHistory
value you’re using in your updater function is accurate, as it refers to the state at the time that specific update is being applied. Therefore, you might want to console logprevHistory
instead:This helper variable
updatedHistory
will give you insight on the value being enqueued for state update.Alternatively, if you want to do something every time
conversationHistory
is being updated, consider using theuseEffect
hook:This hook will be triggered every time
conversationHistory
changes, ensuring accurate reads every time.create a new array that combines the user message and the response with the existing history: