Fully controlled input jumping to start of document
ddormer opened this issue · 3 comments
I'm in need of a fully controlled input as occasionally the editor's content needs to be replaced from an outside source and the performance issues are not a concern for me.
When using a fully controlled value, the input text area keeps resetting the scroll position to the top of the area when inputting text when scrolled down. Presumably this is because the component is being re-rendered on each keystroke and the editor doesn't remember the last scrolled position.
Do you perhaps know of a way to fix this sort of problem? Perhaps EditorView/EditorState can be stored and re-used somehow?
as occasionally the editor's content needs to be replaced from an outside source
You don't need a fully controlled input for that. I would really recommend against any sort of controlled behavior as CodeMirror does not work well with that. You could just pass the new value from the external source into the value prop and it will only update the editor when that value changes. No need to setEditorValue
with the new doc value onUpdate
.
the input text area keeps resetting the scroll position to the top of the area when inputting text when scrolled down
That's odd. I thought I fixed this by preserving the selection when the value changes. I'll look into it, but this should be working.
Nevermind, I got selection and scroll position confused. It looks like you might have to set scrollIntoView
when updating the value. I'm against supporting this when the prop changes because not everyone may want this behavior. I'm also against preserving selection (again because not everyone may want this), but I already added it so it'd be a breaking change to remove. You can get a reference to editorView
and handle the transaction yourself, which will allow you to pass any options you want.
You're right, I could lift the readValue
and writeValue
(referencing rodemirror docs) out of my component and into my top-level data store which would allow bi-directional changes to happen from/to the store-level/app-level while preventing the editor component from re-rendering on keyboard inputs.
I gave the scrollIntoView
a go by handling the transaction myself and it seemed to work out quite well, at least in my limited use-case; Other than autocomplete and slower rendering, is there anything else to worry about though?
Thanks for the help btw, your CodeMirror wrapper has been a great library to use :)
You're right, I could lift the readValue and writeValue (referencing rodemirror docs) out of my component and into my top-level data store
Sounds a bit complicated but that is what I'd recommend.
Other than autocomplete and slower rendering, is there anything else to worry about though?
Something to note is that CodeMirror also sends transactions to update the document on each keystroke, but it doesn't replace the entire document because it can determine where the new value is inserted. When you update the value
prop here, it replaces the entire document, so any extensions will have to be re-run for the entire document and state will be completely refreshed. So while I've only noticed it breaking autocomplete and way worse performance, it might affect other extensions too.