Skip to content

Memoize debounced submit and add cleanup#603

Merged
MakinoharaShoko merged 2 commits into
devfrom
fix-text-editor
May 28, 2026
Merged

Memoize debounced submit and add cleanup#603
MakinoharaShoko merged 2 commits into
devfrom
fix-text-editor

Conversation

@MakinoharaShoko

Copy link
Copy Markdown
Member

Close #601

@MakinoharaShoko MakinoharaShoko linked an issue May 13, 2026 that may be closed by this pull request

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the TextEditor component by introducing a debounced submitChange function memoized with useMemo and adding a cleanup effect. Feedback suggests using flush() instead of cancel() in the cleanup to prevent data loss of pending changes. Additionally, it is recommended to memoize the handleChange function using useCallback and update the imports accordingly to optimize performance and prevent unnecessary re-renders of the editor component.


useEffect(() => {
return () => {
submitChange.cancel();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cancel() in the cleanup effect will discard any pending changes if the component unmounts or the file path changes before the 500ms debounce timer expires. For a text editor where data persistence is critical, it is recommended to use flush() instead. This ensures that any final keystrokes are submitted to the API before the debounced function is disposed.

Suggested change
submitChange.cancel();
submitChange.flush();

import * as monaco from 'monaco-editor';
import Editor, { Monaco } from '@monaco-editor/react';
import { useEffect, useRef } from 'react';
import { useEffect, useMemo, useRef } from 'react';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The useCallback hook should be imported from 'react' to allow memoizing the handleChange callback, which is a best practice when passing functions to complex child components like the Monaco Editor.

Suggested change
import { useEffect, useMemo, useRef } from 'react';
import { useCallback, useEffect, useMemo, useRef } from 'react';

Comment on lines +125 to +128
const handleChange = (value: string | undefined, ev: monaco.editor.IModelContentChangedEvent) => {
if (!isEditorReady.value) return;
submitChange(value, ev);
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The handleChange function is currently recreated on every render. Since it is passed as a prop to the Editor component, it should be memoized using useCallback. This ensures that the Editor component doesn't receive a new function reference unless its dependencies change, which can prevent unnecessary internal updates or side effects within the editor wrapper.

Suggested change
const handleChange = (value: string | undefined, ev: monaco.editor.IModelContentChangedEvent) => {
if (!isEditorReady.value) return;
submitChange(value, ev);
};
const handleChange = useCallback((value: string | undefined, ev: monaco.editor.IModelContentChangedEvent) => {
if (!isEditorReady.value) return;
submitChange(value, ev);
}, [submitChange, isEditorReady]);

@MakinoharaShoko MakinoharaShoko requested a review from HardyNLee May 18, 2026 18:08
# Conflicts:
#	packages/origine2/src/pages/editor/TextEditor/TextEditor.tsx
@MakinoharaShoko MakinoharaShoko merged commit 86bf75f into dev May 28, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

初始化文本编辑器防止误提交问题

1 participant