Closed tyagirajat200 closed 8 months ago
That's surprising. The lib only uses an effect to update the model when the prop change, I have no idea how it can happen and I'm unable to reproduce.
The component is not so complicated, are you able to investigate a little bit? (debugging the effect)
I tried to debug the issue and found that the fixedCode !== model.getValue() condition returns true only when I'm typing rapidly. In such cases, it sets the value again. This might be happening because we are using a debounce function in the onChange event handler.
useEffect(() => {
if (fixedCode != null) {
const model = modelRef.current;
const editor = editorRef.current;
if (fixedCode !== model.getValue()) {
preventTriggerChangeEventRef.current = true;
console.debug('Replacing whole editor content');
editor.pushUndoStop();
model.setValue(fixedCode);
editor.pushUndoStop();
preventTriggerChangeEventRef.current = false;
}
}
}, [fixedCode]);
useEffect(() => {
if (onChange != null) {
// Sometimes, monaco calls the didChangeModelContent multiple times in a row
// (For instance, after an autocomplete with some additionalTextEdits - used by the typescript language server)
// The onChange prop is very probably used to store the current code in a state somewhere
// Updating that state 2 times in a row will trigger 2 asynchronous renders
// The first render will use the state after the first model content change, while the monaco model is already up to date with the last change
// It will then produce a desync and this component will overwrite the editor content to sync it back
// Doing so produces at least 2 issues: the cursor is moved to the beginning of the file by monaco and the undo stack is lost
// So a solution is to debounce the onChange callback so it's called only once in that case
const debouncedOnChange = debounce(onChange, 0);
const editor = editorRef.current;
const didChangeModelContentDisposable = editor.onDidChangeModelContent(event => {
if (!preventTriggerChangeEventRef.current) {
debouncedOnChange(editor.getValue(), event);
}
});
return () => {
didChangeModelContentDisposable.dispose();
};
}
return undefined;
}, [onChange]);
That's funny, that code is there exactly to prevent that issue (:
I'm surprised it can have this impact as it's just a setTimeout(0) and I don't know how you can type THAT fast to be able to enter 2 chars.
I'm unable to reproduce though, can you provide some hints? What browser are you using?
I was using latest version of chrome. This issue was resolved by removing the setTimeout.
I have one more issue if I create multiple models beforehand then on setting the model in the monaco editor below error is coming - main.js:3283 Unexpected error TypeError: Cannot read properties of undefined (reading 'match') at MonarchModernTokensCollector.emit (monarchLexer.js:239:1) at MonarchTokenizer._myTokenize (monarchLexer.js:714:1) at MonarchTokenizer._tokenize (monarchLexer.js:394:1) at MonarchTokenizer.tokenizeEncoded (monarchLexer.js:386:1) at safeTokenize (textModelTokens.js:415:37) at TextModelTokenization._updateTokensUntilLine (textModelTokens.js:338:23) at TextModelTokenization._tokenizeOneInvalidLine (textModelTokens.js:324:14) at TextModelTokenization._backgroundTokenizeForAtLeast1ms (textModelTokens.js:228:46) at execute (textModelTokens.js:201:18) at TextModelTokenization._backgroundTokenizeWithDeadline (textModelTokens.js:212:9) With this syntax highlighting is not working.
I imported monaco directly from "monaco-editor" in one of the files. This is fixed.
While I'm typing rapidly within the editor, the cursor has a tendency to unexpectedly leap to the start of the file.
Here's the code snippet I'm utilizing:
The problem doesn't arise when I don't provide the 'value' attribute. I suspect the issue stems from the fact that the updated value is being consistently passed to the editor upon each change.