mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-06-12 04:33:34 +08:00
fix: avoid flushSync call during <EditorContent /> lifecycle
This commit is contained in:
parent
aff018e651
commit
1f5a830e5b
@ -3,7 +3,7 @@ import { ReactPortal } from 'react'
|
||||
|
||||
import { ReactRenderer } from './ReactRenderer.js'
|
||||
|
||||
export type EditorWithContentComponent = Editor & { contentComponent?: ContentComponent | null }
|
||||
export type EditorWithContentComponent = Editor & { contentComponent?: ContentComponent | null; isEditorContentInitialized?: boolean }
|
||||
export type ContentComponent = {
|
||||
setRenderer(id: string, renderer: ReactRenderer): void;
|
||||
removeRenderer(id: string): void;
|
||||
|
@ -98,18 +98,9 @@ export class PureEditorContent extends React.Component<
|
||||
> {
|
||||
editorContentRef: React.RefObject<any>
|
||||
|
||||
initialized: boolean
|
||||
|
||||
unsubscribeToContentComponent?: () => void
|
||||
|
||||
constructor(props: EditorContentProps) {
|
||||
super(props)
|
||||
this.editorContentRef = React.createRef()
|
||||
this.initialized = false
|
||||
|
||||
this.state = {
|
||||
hasContentComponentInitialized: Boolean((props.editor as EditorWithContentComponent | null)?.contentComponent),
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -138,29 +129,11 @@ export class PureEditorContent extends React.Component<
|
||||
|
||||
editor.contentComponent = getInstance()
|
||||
|
||||
// Has the content component been initialized?
|
||||
if (!this.state.hasContentComponentInitialized) {
|
||||
// Subscribe to the content component
|
||||
this.unsubscribeToContentComponent = editor.contentComponent.subscribe(() => {
|
||||
this.setState(prevState => {
|
||||
if (!prevState.hasContentComponentInitialized) {
|
||||
return {
|
||||
hasContentComponentInitialized: true,
|
||||
}
|
||||
}
|
||||
return prevState
|
||||
})
|
||||
|
||||
// Unsubscribe to previous content component
|
||||
if (this.unsubscribeToContentComponent) {
|
||||
this.unsubscribeToContentComponent()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
editor.createNodeViews()
|
||||
|
||||
this.initialized = true
|
||||
editor.isEditorContentInitialized = true
|
||||
|
||||
this.forceUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +144,7 @@ export class PureEditorContent extends React.Component<
|
||||
return
|
||||
}
|
||||
|
||||
this.initialized = false
|
||||
editor.isEditorContentInitialized = false
|
||||
|
||||
if (!editor.isDestroyed) {
|
||||
editor.view.setProps({
|
||||
@ -179,10 +152,6 @@ export class PureEditorContent extends React.Component<
|
||||
})
|
||||
}
|
||||
|
||||
if (this.unsubscribeToContentComponent) {
|
||||
this.unsubscribeToContentComponent()
|
||||
}
|
||||
|
||||
editor.contentComponent = null
|
||||
|
||||
if (!editor.options.element.firstChild) {
|
||||
|
@ -78,7 +78,7 @@ type ComponentType<R, P> =
|
||||
export class ReactRenderer<R = unknown, P extends Record<string, any> = object> {
|
||||
id: string
|
||||
|
||||
editor: Editor
|
||||
editor: EditorWithContentComponent
|
||||
|
||||
component: any
|
||||
|
||||
@ -101,7 +101,7 @@ export class ReactRenderer<R = unknown, P extends Record<string, any> = object>
|
||||
}: ReactRendererOptions) {
|
||||
this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString()
|
||||
this.component = component
|
||||
this.editor = editor as EditorWithContentComponent
|
||||
this.editor = editor
|
||||
this.props = props as P
|
||||
this.element = document.createElement(as)
|
||||
this.element.classList.add('react-renderer')
|
||||
@ -110,7 +110,7 @@ export class ReactRenderer<R = unknown, P extends Record<string, any> = object>
|
||||
this.element.classList.add(...className.split(' '))
|
||||
}
|
||||
|
||||
if (this.editor.isInitialized) {
|
||||
if (this.editor.isEditorContentInitialized) {
|
||||
// On first render, we need to flush the render synchronously
|
||||
// Renders afterwards can be async, but this fixes a cursor positioning issue
|
||||
flushSync(() => {
|
||||
|
Loading…
Reference in New Issue
Block a user