I am working on a chat application and I have a feature where users can select prompts. When a user selects a prompt, you want the chat input to automatically populate with the selected prompt and submit the form.
However, I am encountering an issue where the form is not being submitted automatically when the input changes after a prompt is selected. I’ve tried to programmatically dispatch a submit event on the form and directly call the onSubmit
function from a useEffect
hook, but neither approach is working as expected.
The main challenge here is dealing with the asynchronous nature of state updates in React. When I update the selectedPrompt
state, it doesn’t immediately re-render the component. Therefore, the useEffect
hook might not have the latest selectedPrompt
value when it tries to click the submit button.
import React, { useState, useEffect, useRef } from "react";
import { Button } from "../button";
import FileUploader from "../file-uploader";
import { Input } from "../input";
import UploadImagePreview from "../upload-image-preview";
import { ChatHandler } from "./chat.interface";
import { ArrowUp } from 'lucide-react';
interface ChatInputProps extends Pick<
ChatHandler,
"isLoading" | "input" | "onFileUpload" | "onFileError" | "handleSubmit" | "handleInputChange"
> {
multiModal?: boolean;
selectedPrompt: string;
setSelectedPrompt: (prompt: string) => void;
}
export default function ChatInput({
isLoading,
input,
onFileUpload,
onFileError,
handleSubmit,
handleInputChange,
multiModal,
selectedPrompt,
setSelectedPrompt
}: ChatInputProps) {
const [imageUrl, setImageUrl] = useState<string | null>(null);
const formRef = useRef<HTMLFormElement>(null);
useEffect(() => {
if (selectedPrompt) {
handleInputChange({ target: { value: selectedPrompt } } as React.ChangeEvent<HTMLInputElement>);
if (formRef.current) {
formRef.current.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
}
setSelectedPrompt('');
}
}, [selectedPrompt]);
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (selectedPrompt) {
handleSubmit(e, { data: { imageUrl } });
setImageUrl(null);
setSelectedPrompt('');
} else {
handleSubmit(e);
}
};
return (
<form ref={formRef} onSubmit={onSubmit}>
<Input
name="message"
placeholder=""
value={input}
onChange={handleInputChange}
/>
<button
type="submit"
>
</button>
</form>
);
}
The selected prompt is passed into the input as soon as the updates, the form is supposed to submitted as well but its having issues.
tried debugging using logging and debugging also tried stepping through the code