scniro / react-codemirror2

Codemirror integrated components for React
MIT License
1.66k stars 193 forks source link

Editor Duplicating #284

Open mezplz opened 2 years ago

mezplz commented 2 years ago

Hi, I use react-codemirror2 7.2.1 and React 18, I got the editor duplicating. When I use React17, it worked fine. Is there anyway to fix ?

jdz321 commented 2 years ago

This issue is caused by a new feature in React18: https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state I saw this question for a friend, and solved this way. I simply removed the editor dom, there should be a more appropriate way.

function App() {
  const editor = useRef()
  const wrapper = useRef()
  const editorWillUnmount = () => {
    editor.current.display.wrapper.remove()
    wrapper.current.hydrated = false
  }
  return (
    <div className="App">
      <CodeMirror
        value='<h1>I ♥ react-codemirror2</h1>'
        ref={wrapper}
        options={{
          mode: 'xml',
          theme: 'material',
          lineNumbers: true
        }}
        onChange={(editor, data, value) => {
        }}
        editorDidMount={(e) => editor.current = e}
        editorWillUnmount={editorWillUnmount}
      />
    </div>
  );
}
undeletable commented 11 months ago

@jdz321 Thanks a lot! This works for me too. I'd like to add a note for the ones who use TypeScript like me: this is not type safe solution, since display and hydrated properties aren't exposed as public properties of the corresponding interfaces. So you'll have either to add type assertions to any for them, or add ignore comment. Sounds dirty, but the whole solution is a hack.

bilalesi commented 4 months ago

for anyone looking for TS solutions

          editorDidMount={editorElement => {
            (editorRef as React.MutableRefObject<
              codemirror.Editor
            >).current = editorElement;
          }}
          editorWillUnmount={() => {
            const editorWrapper = (editorRef as React.MutableRefObject<
              CodeMirror.Editor
            >).current.getWrapperElement();
            if (editorWrapper) editorWrapper.remove();
            if (wrapperRef.current) {
              (wrapperRef.current as { hydrated: boolean }).hydrated = false;
            }
          }}