mirror of
https://github.com/Kong/insomnia.git
synced 2026-08-04 11:52:33 -04:00
fix: cancel stale debounce on blur in OneLineEditor to prevent race condition
When the user blurs a field immediately after typing (e.g. clicking Add Row), the 100ms debounce could fire after the subsequent write, overwriting the DB with stale kvPairs that didn't include the new row. Fix by: adding cancel() to misc.debounce, merging changes/blur into a single effect registered once via a ref (eliminating stale closures), and having blur explicitly cancel any pending debounce before flushing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -109,6 +109,7 @@ export const debounce = <F extends (...args: Parameters<F>) => ReturnType<F>>(
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func(...args), waitFor);
|
||||
};
|
||||
debounced.cancel = () => clearTimeout(timeout);
|
||||
|
||||
return debounced;
|
||||
};
|
||||
|
||||
@@ -65,6 +65,8 @@ export const OneLineEditor = forwardRef<OneLineEditorHandle, OneLineEditorProps>
|
||||
) => {
|
||||
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const codeMirror = useRef<CodeMirror.EditorFromTextArea | null>(null);
|
||||
const onChangeRef = useRef(onChange);
|
||||
onChangeRef.current = onChange;
|
||||
const { settings } = useRootLoaderData()!;
|
||||
const { isOwner, isEnterprisePlan } = usePlanData();
|
||||
const { handleRender, handleGetRenderContext } = useNunjucks();
|
||||
@@ -296,23 +298,26 @@ export const OneLineEditor = forwardRef<OneLineEditorHandle, OneLineEditorProps>
|
||||
|
||||
useEffect(() => {
|
||||
const fn = misc.debounce((doc: CodeMirror.Editor) => {
|
||||
if (onChange) {
|
||||
onChange(doc.getValue() || '');
|
||||
if (onChangeRef.current) {
|
||||
onChangeRef.current(doc.getValue() || '');
|
||||
}
|
||||
}, DEBOUNCE_MILLIS);
|
||||
codeMirror.current?.on('changes', fn);
|
||||
return () => codeMirror.current?.off('changes', fn);
|
||||
}, [onChange]);
|
||||
|
||||
useEffect(() => {
|
||||
const flushOnBlur = (doc: CodeMirror.Editor) => {
|
||||
if (onChange) {
|
||||
onChange(doc.getValue() || '');
|
||||
// Cancel the pending debounce so a stale fire can't overwrite state after blur
|
||||
fn.cancel();
|
||||
if (onChangeRef.current) {
|
||||
onChangeRef.current(doc.getValue() || '');
|
||||
}
|
||||
};
|
||||
codeMirror.current?.on('changes', fn);
|
||||
codeMirror.current?.on('blur', flushOnBlur);
|
||||
return () => codeMirror.current?.off('blur', flushOnBlur);
|
||||
}, [onChange]);
|
||||
return () => {
|
||||
fn.cancel();
|
||||
codeMirror.current?.off('changes', fn);
|
||||
codeMirror.current?.off('blur', flushOnBlur);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = window.main.on(
|
||||
|
||||
Reference in New Issue
Block a user