🖌️

CodeMirrorをベースとしたエディターでCtrl + Zを実行すると内容が全て消える問題を解消する

2021/09/12に公開

まだ日本語の情報がないようなので残しておきます。
CodeMirrorをベースにしたエディターライブラリで、マウント直後にCtrl + Z⌘ + Z)のショートカットを実行すると内容がすべて消えてしまう(空になる)問題が起きることがあります。

例えばEasyMDE(v2.15.1-477.0)でこの問題が発生します。デモページを開きエディターにフォーカスをあてた状態でCtrl + Z⌘ + Z)を実行すると内容が消えることが分かります。

原因

原因は、マウント時点で(本文の初期データが渡される前に)CodeMirrorインスタンスのvalueに空の値が入ってしまい、その空の値が編集履歴に残されてしまうのだと考えられます。

解決策

初期データを入れた後に、一旦CodeMirrorインスタンスが持つ編集履歴をクリアすれば問題は解決します。CodeMirrorのAPIにclearHistory()というものがあるので、これをエディターのマウント後に呼び出してやれば良さそうです。

例えば、EasyMDEのReactのラッパーライブラリであるReact SimpleMDEを使う場合には以下のように書けます。

import SimpleMDE from 'react-simplemde-editor';

export const MyEditor = () => {
  const [body, setBody] = useState("本文のデフォルトテキスト");
  const [cmInstance, setCmInstance] = useState(null);
  const getCmInstanceCallback = useCallback((editor) => {
    setCmInstance(editor);
  }, []);

  useEffect(() => {
    if (!cmInstance) return;
    cmInstance.doc.clearHistory();
  }, [cmInstance]);

  // React SimpleMDEでは`getCodemirrorInstance`というpropsで
  // CodeMirrorインスタンスを取り出せる
  return (
    <SimpleMDE
      value={body}
      onChange={setBody}
      getCodemirrorInstance={getCmInstanceCallback}
    />
  );
}

👇 CodeSandboxも作りました。

Discussion