fix: avoid stale closure in keyboard submit handler

This commit is contained in:
Alejandro Gómez
2026-03-16 16:14:47 +01:00
parent 0aecdd6894
commit 02ec642be6
2 changed files with 25 additions and 14 deletions

View File

@@ -671,6 +671,8 @@ export function ChatViewer({
// Track reply context (which message is being replied to)
const [replyTo, setReplyTo] = useState<string | undefined>();
const replyToRef = useRef<string | undefined>(undefined);
replyToRef.current = replyTo;
// State for loading older messages
const [isLoadingOlder, setIsLoadingOlder] = useState(false);
@@ -1210,7 +1212,12 @@ export function ChatViewer({
}}
onSubmit={(content, emojiTags, blobAttachments) => {
if (content.trim()) {
handleSend(content, replyTo, emojiTags, blobAttachments);
handleSend(
content,
replyToRef.current,
emojiTags,
blobAttachments,
);
}
}}
className="flex-1 min-w-0"

View File

@@ -7,6 +7,7 @@ import {
useRef,
} from "react";
import { useEditor, EditorContent } from "@tiptap/react";
import type { Editor } from "@tiptap/core";
import Mention from "@tiptap/extension-mention";
import StarterKit from "@tiptap/starter-kit";
import Placeholder from "@tiptap/extension-placeholder";
@@ -77,22 +78,25 @@ export const MentionEditor = forwardRef<
},
ref,
) => {
const handleSubmitRef = useRef<(editor: any) => void>(() => {});
// Use a ref for onSubmit to avoid stale closures in TipTap keyboard handlers.
// The Enter key handler reads this ref at invocation time, ensuring it always
// has the latest callback (including any captured reply context).
const onSubmitRef = useRef(onSubmit);
onSubmitRef.current = onSubmit;
const handleSubmit = useCallback(
(editorInstance: any) => {
if (!editorInstance || !onSubmit) return;
const handleSubmit = useCallback((editorInstance: Editor) => {
const cb = onSubmitRef.current;
if (!cb) return;
const { text, emojiTags, blobAttachments } =
serializeInlineContent(editorInstance);
if (text) {
onSubmit(text, emojiTags, blobAttachments);
editorInstance.commands.clearContent();
}
},
[onSubmit],
);
const { text, emojiTags, blobAttachments } =
serializeInlineContent(editorInstance);
if (text) {
cb(text, emojiTags, blobAttachments);
editorInstance.commands.clearContent();
}
}, []);
const handleSubmitRef = useRef(handleSubmit);
handleSubmitRef.current = handleSubmit;
// React-based suggestion renderers (replace tippy.js + ReactRenderer)