Bernard
Bernard

Reputation: 11

Implementing CodeMirror 6 in React: how to replace full value/code?

I have a state that maintains the code. code can be updated externally, or in the CodeMirror 6 editor by the user, which then updates setCode. (In my example code I updated this to a local state, as example.)

How do I update my CodeMirror's value when code is changed externally?

A simplified situation of my code:

import React, { useState, useRef, useEffect } from 'react';

import { basicSetup, EditorView } from 'codemirror';
import { EditorState, Compartment } from '@codemirror/state';
import { keymap } from '@codemirror/view';
import { defaultKeymap } from '@codemirror/commands';


const CodeEditor: React.FC = () => {
  const [code, setCode] = useState("initial code state that can be changed externally");
  
  const editor = useRef<any>();
  const valueRef = useRef<string>(code);

  useEffect(() => {
    valueRef.current = code;
  }, [code]);

  useEffect(() => {
    // CodeMirror Extension: update code in store
    const onUpdate = EditorView.updateListener.of((v) => {
        setCode(v.state.doc.toString());
    });
    
    const codeMirrorOptions = {
      doc: valueRef.current,
      lineNumbers: true,
      lineWrapping: true,
      width: '300px',
      autoCloseBrackets: true,
      cursorScrollMargin: 48,
      indentUnit: 2,
      tabSize: 2,
      styleActiveLine: true,
      viewportMargin: 99,
      extensions: [
        basicSetup,
        keymap.of(defaultKeymap),
        onUpdate,
      ],
    };

    const startState = EditorState.create(codeMirrorOptions);

    const view = new EditorView({
      state: startState,
      parent: editor.current,
    });

    return () => {
      view.destroy();
    };
  }, []);


  return <div ref={editor} />;
};

export default CodeEditor;

(Freely derived from among others, this answer: https://stackoverflow.com/a/71071618/2728820)

Upvotes: 0

Views: 1838

Answers (1)

user3009344
user3009344

Reputation:

view.dispatch({
    changes: {
        from: 0,
        to: view.state.doc.length,
        insert: state
    }
})

You can read more about it in code mirror examples.

Upvotes: 0

Related Questions