Skip to content

fix(scratch-pad): 修复空格无法输入和换行被吞的 content 同步循环#461

Merged
ErlichLiu merged 1 commit into
mainfrom
fix/scratch-pad-space-newline-input
May 15, 2026
Merged

fix(scratch-pad): 修复空格无法输入和换行被吞的 content 同步循环#461
ErlichLiu merged 1 commit into
mainfrom
fix/scratch-pad-space-newline-input

Conversation

@ErlichLiu
Copy link
Copy Markdown
Owner

问题

ScratchPad 编辑器存在两个输入异常:

  • 空格无法正常输入(输入后被吞掉)
  • 按 Enter 产生的换行被吞掉

根因分析

useEffectcontent atom 加入依赖数组,导致以下死循环:

用户按键(空格/Enter)
  → TipTap onUpdate → setContent(editor.getHTML()) → atom 更新
  → content 变化触发 useEffect → editor.commands.setContent(content)
  → ProseMirror DOMParser 解析 HTML(规范化)
    ├─ 尾部空格被 HTML 解析器吃掉("Hello " → "Hello")
    └─ 空段落 <p></p> 被剥离(换行被吞)
  → 光标位置重置 → onUpdate 再次触发 → 循环

修复方案

  • contentuseEffect 依赖数组移除
  • 引入 contentRef 追踪最新内容值(避免 stale closure)
  • 添加 editor.getHTML() !== latestContent 比对,只在内容真正不同时调用 setContent

useEffect 现在只在 loaded/editor 变化时触发(初始加载 + Tab 重新挂载),用户输入不再触发 setContent,消除循环。

测试

  • 打开 Scratch Pad,正常输入空格
  • 按 Enter 换行不被吞掉
  • 切换 Tab 后回来内容正常恢复
  • 首次加载内容从磁盘正确同步

🤖 Generated with Claude Code

将 content 从 useEffect deps 移除,引入 contentRef 访问最新值。

根因:useEffect 包含 content 依赖,每次用户输入都会触发
editor.commands.setContent() 调用,ProseMirror DOMParser 规范化
HTML 时会吞掉尾部空格和空段落,并重置光标位置。

修复后 useEffect 仅在 loaded/editor 变化(初始加载/Tab 重新挂载)
时同步内容,用户输入不再触发 setContent,消除死循环。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ErlichLiu ErlichLiu merged commit 91e4a39 into main May 15, 2026
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