use-prosemirror: editorView.state is out of sync until rerender of ProseMirror has completed
Hi there!
I’m integrating ProseMirror with your approach using React. Along with ProseMirror I’m rendering an EditorMenu that computes and renders editor tools.
Here’s my integration code:
export default function Editor (props) {
const [editorView, setEditorView] = useState(null)
const [state, setState] = useProseMirror({
doc: DOMParser.fromSchema().parse(buildHTML()),
plugins: [
keymap(buildKeymap(schema)),
keymap(baseKeymap),
history(),
dropCursor()
]
})
useEffect(() => {
setEditorView(viewRef.current.view)
}, [])
const viewRef = useRef()
return (
<div className='flex flex-col h-screen'>
<header className='p-5 bg-white shadow'>
<EditorMenu editorView={editorView} />
</header>
<main className='flex-1 overflow-y-auto p-5 article'>
<div className='max-w-4xl mx-auto py-6 sm:px-6 lg:px-8'>
<ProseMirror
ref={viewRef}
state={state}
onChange={newState => {
// HACK: Update the editor view right away, so in EditorMenu editorView.state reflects newState
viewRef.current.view.updateState(newState)
setState(newState)
}}
/>
</div>
</main>
</div>
)
}
The menu bar thus is one update cycle behind. I solved this problem by running editorView.updateState(newState) in the onChange handler explicitly. However, I wonder what an idiomatic way of doing this would be? I could pass both state and editorView to EditorMenu, but that complicates the interface a bit. I kinda like that ProseMirror and EditorMenu are part of the same render flow with useProseMirror. In my previous integration the EditorMenu was decoupled and was listening to state updates. I also wonder if there’s a better way to provide editorView to EditorMenu. Would be nice not avoid using another component state + useEffect for that. I’m quite new to Function Components — not been using React in a while. 😅 Maybe you have some ideas…
Thank you!
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 16 (8 by maintainers)
Hey just wanted to say again thank you! I’ve sticked with setState in the end, as it just feels more natural. But I can say I’ve managed to come up with a cursor dependent overlay, as well as modal dialogs etc. in a very minimal way using your approach!
I’ll do an iteration or two more and then would love to share some code, and have your opinion. And maybe you want to use it as a more complete integration example. I favor your little module much over more complete and opinionated React-Frameworks for ProseMirror. 👏 Think people should know! 😃