react-codemirror
react-codemirror copied to clipboard
How to get instance
How do you get access to the codemirror editor instance so that you can use the api?
For example
https://codemirror.net/doc/manual.html#api
See
doc.markText(from: {line, ch}, to: {line, ch}, ?options: object)
So how can I get access to an editor instance so I can get the doc object?
If you are currently using the latest version of uiwjs/react-codemirror
, then you can get the EditorView
, EditorState
and HTMLDivElement
instances of CodeMirror with the ref
parameter:
import React from "react";
import CodeMirror, { ReactCodeMirrorRef } from "@uiw/react-codemirror";
import { javascript } from "@codemirror/lang-javascript";
export default function App() {
const refs = React.useRef<ReactCodeMirrorRef>({});
React.useEffect(() => {
if (refs.current?.view) console.log('EditorView:', refs.current?.view);
if (refs.current?.state) console.log('EditorState:', refs.current?.state);
if (refs.current?.editor) console.log('HTMLDivElement:', refs.current?.editor);
}, [refs.current]);
return (
<>
<CodeMirror
ref={refs}
value="console.log('hello world!');"
height="200px"
extensions={[javascript({ jsx: true })]}
/>
</>
);
}
Thank you so much, that is exactly what I needed!
@thebpmgroup Were you able to get doc.markText ? If yes, can you please clarify how did you get it ? Thanks, Ameya
@ameya730
I think doc.markText
was a CodeMirror 5 feature. For CodeMirror 6, you might want to look into Decoration.mark
.
It doesn't work anymore, when using the same code like @Gk0Wk provided, I get only the HTMLDivElement, but I don't get state and view, they undefined
- https://github.com/uiwjs/react-codemirror/issues/499#issuecomment-1556070183
@thewh1teagle
@jaywcjlove
I try to use it in useEffect
but the state
and view
is undefined
my goal is to set default line number. so the editor will be positioned to specific line at first render.
App.ts
import React, { useRef, useState } from "react";
import CodeMirror from "@uiw/react-codemirror";
import { javascript } from "@codemirror/lang-javascript";
export default function App() {
const $edit = useRef();
const [val, setVal] = useState("console.log('hello world!');");
const onChange = React.useCallback((value, viewUpdate) => {
console.log("value:", value);
}, []);
const onRefChange = () => {
$edit.current.view.dispatch({
changes: { from: 0, to: 12, insert: "test" + new Date() }
});
};
/* --------- here -------- */
useEffect(() => {
console.log($edit.current.state) // undefined
console.log($edit.current.view) // undefined
}, [$edit.current])
return (
<div>
<button onClick={() => setVal("Time: " + new Date())}>
Change Value
</button>
<button onClick={onRefChange}>Ref Change Value</button>
<CodeMirror
value={val}
ref={$edit}
height="200px"
theme="dark"
extensions={[javascript({ jsx: true })]}
onChange={onChange}
/>
</div>
);
}
@thebpmgroup
useEffect(() => {
console.log($edit.current.state) // undefined
console.log($edit.current.view) // undefined
}, [
- $edit.current
+ $edit
])
@jaywcjlove
That's working because you test it on CodeSandbox
.
refresh the page and see that in the first useEffect
state and view are undefined
@thebpmgroup https://codesandbox.io/s/react-codemirror-example-codemirror-6-https-github-com-uiwjs-react-codemirror-issues-314-w64xo4
@jaywcjlove
Here you can see also in the link you sent.
Tried in Firefox
, Chrome
To reproduce it, you need to refresh the page and see the initial useEffect
log into the console
@thebpmgroup I didn't find a better solution, but the following solution may help you:
useEffect(()=> {
console.log('$edit:', $edit)
setTimeout(() => {
console.log('$edit:view:', $edit.current?.view)
console.log('$edit:state:', $edit.current?.state)
}, 300)
console.log('$edit:', $edit.current?.view)
}, [$edit])
It's a bug in the library... I found this workround:
import CodeMirror from "@uiw/react-codemirror";
import { useRef } from "react";
export default function App() {
const ref = useRef();
function refCallack(editor) {
if (!ref.current && editor?.editor && editor?.state && editor?.view) {
// first time we got ref, similar to useEffect
console.log(editor); // do something with editor
ref.current = editor; // store it
}
}
return <CodeMirror ref={refCallack} value="console.log('hello world!');" />;
}
https://codesandbox.io/embed/react-codemirror-example-codemirror-6-https-github-com-uiwjs-react-codemirror-issues-314-w64xo4?fontsize=14&hidenavigation=1&theme=dark
@thewh1teagle 👍
Hum, I’m a bit lost as well: how do you get access to doc
that is needed all over the API, for instance to do replaceSelection
? I tried:
const onHelperMenuClick = useCallback((e) => {
// Works, but is not what I want:
// refCodemirror.current.view.dispatch({
// changes: { from: 0, to: 1, insert: "test" + new Date() }
// });
// Fails:
if (refCodemirror.current) {
console.log('HTMLDivElement:', refCodemirror.current.editor);
const doc = refCodemirror.current.editor.getDoc();
console.log(doc);
doc.replaceSelection(e.key);
}
});
Oh, seems like I needed to send this to dispatch, like:
const onHelperMenuClick = useCallback((e) => {
// https://github.com/uiwjs/react-codemirror/issues/314
if (refCodemirror.current) {
console.log('HTMLDivElement:', refCodemirror.current.editor);
const doc = refCodemirror.current.view.state;
refCodemirror.current.view.dispatch(doc.replaceSelection(e.key));
}
});
It's a bug in the library... I found this workround:
import CodeMirror from "@uiw/react-codemirror"; import { useRef } from "react"; export default function App() { const editorRef = useRef<ReactCodeMirrorRef>(); function editorRefCallack(editor: ReactCodeMirrorRef) { if (!editorRef.current && editor?.editor && editor?.state && editor?.view) { console.log(editor); editorRef.current = editor; } } return <CodeMirror ref={editorRefCallback} value="console.log('hello world!');" />; }
it works! thank you so much..!