fix: 修复 markdown 编辑保存后内容丢失的问题
- 在 saveContent 中缓存 unsavedContent,避免 async 期间的竞态条件 - 在 useMarkdownLogic 中添加 lastContentRef 跟踪内容变化,防止不必要的编辑器更新
This commit is contained in:
@@ -85,6 +85,8 @@ export const useMarkdownLogic = ({
|
|||||||
const readOnlyRef = useRef(readOnly)
|
const readOnlyRef = useRef(readOnly)
|
||||||
const ctxRef = useRef<Ctx | null>(null)
|
const ctxRef = useRef<Ctx | null>(null)
|
||||||
|
|
||||||
|
const lastContentRef = useRef<string>('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onChangeRef.current = onChange
|
onChangeRef.current = onChange
|
||||||
}, [])
|
}, [])
|
||||||
@@ -117,23 +119,28 @@ export const useMarkdownLogic = ({
|
|||||||
}
|
}
|
||||||
}, [readOnly])
|
}, [readOnly])
|
||||||
|
|
||||||
// 在只读模式下动态更新内容
|
// 在只读模式下动态更新内容(仅当 content 真正变化时)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ctxRef.current || !readOnly) return
|
if (!ctxRef.current || !readOnly) return
|
||||||
|
|
||||||
|
// 只有当 content 真正变化时才更新编辑器
|
||||||
|
if (content === lastContentRef.current) return
|
||||||
|
lastContentRef.current = content
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const view = ctxRef.current.get(editorViewCtx)
|
const view = ctxRef.current.get(editorViewCtx)
|
||||||
const parser = ctxRef.current.get(parserCtx)
|
const parser = ctxRef.current.get(parserCtx)
|
||||||
const doc = parser(content)
|
const doc = parser(content)
|
||||||
if (!doc) return
|
if (!doc) return
|
||||||
|
|
||||||
const state = view.state
|
view.dispatch(view.state.tr.replaceWith(0, view.state.doc.content.size, doc))
|
||||||
view.dispatch(state.tr.replaceWith(0, state.doc.content.size, doc))
|
|
||||||
} catch {
|
} catch {
|
||||||
// 编辑器可能尚未就绪
|
// 编辑器可能尚未就绪
|
||||||
}
|
}
|
||||||
}, [content, readOnly])
|
}, [content, readOnly])
|
||||||
|
|
||||||
return useEditor((root) => {
|
return useEditor((root) => {
|
||||||
|
lastContentRef.current = content
|
||||||
return Editor.make()
|
return Editor.make()
|
||||||
.config((ctx) => {
|
.config((ctx) => {
|
||||||
ctxRef.current = ctx
|
ctxRef.current = ctx
|
||||||
|
|||||||
@@ -331,7 +331,9 @@ export const useTabStore = create<TabStore>((set, get) => {
|
|||||||
const isAsyncImportProcessing = isAsyncImportProcessingContent(tab.content)
|
const isAsyncImportProcessing = isAsyncImportProcessingContent(tab.content)
|
||||||
if (isAsyncImportProcessing) return
|
if (isAsyncImportProcessing) return
|
||||||
|
|
||||||
await saveFileContent(filePath, tab.unsavedContent)
|
const contentToSave = tab.unsavedContent
|
||||||
|
|
||||||
|
await saveFileContent(filePath, contentToSave)
|
||||||
|
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const newTabs = new Map(state.tabs)
|
const newTabs = new Map(state.tabs)
|
||||||
@@ -339,7 +341,8 @@ export const useTabStore = create<TabStore>((set, get) => {
|
|||||||
if (currentTab) {
|
if (currentTab) {
|
||||||
newTabs.set(filePath, {
|
newTabs.set(filePath, {
|
||||||
...currentTab,
|
...currentTab,
|
||||||
content: currentTab.unsavedContent,
|
content: contentToSave,
|
||||||
|
unsavedContent: contentToSave,
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user