実務でReact、TypeScriptを使用しており、2017年で更新が止まっているSimpleMDEから最新のEasyMDEに移行したため、ポイントを整理して共有します。
SimpleMDEの使用で起きた問題
- 最終の更新が2017年であるため、モダンのブラウザへの対応やセキュリティへのメンテナンスがなされていない
- 表示のバグが多い(parentNode関連のエラーによってレンダリングが崩れてしまうことがある)
- 型定義が公式に提供されていないため、型安全に扱いづらい
ReactでのSimpleMDE→EasyMDEの移行ポイント
1.パッケージの置き換えをする
まずnpm/yarnでeasyMDEをインストールして、SimpleMDEのimportを置き換えるようにします。
npm i easymde
//変更前
import SimpleMDE from 'simplemde';
//変更後
import EasyMDE from 'easymde';
2.Reactコンポーネントでの初期化方法
- SimpleMdeReactコンポーネントを削除する
- 代わりにtextareaを配置してrefを渡す
- EasyMDEの初期化はuseEffect内でnew EasyMDE({ element: textAreaRef.current, ... }) で行う
- onChangeはcodemirror.on('change')でReact stateと同期するようにする
元のコード(SimpleMDE)
<SimpleMdeReact
getMdeInstance={handleEditorMount}
onChange={handleContentChange}
options={editorOptions}
value={content}
/>
移行後(EasyMDE)
const editorReference = useRef<EasyMDE | null>(null);
const textAreaRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
if (textAreaRef.current && !editorReference.current) {
editorReference.current = new EasyMDE({
element: textAreaRef.current,
spellChecker: false,
placeholder: "ここに内容を入力してください...",
autofocus: true,
toolbar: ["bold", "italic", "heading"],//ここは必要に応じて変更する
renderingConfig: { singleLineBreaks: true, codeSyntaxHighlighting: true },
});
editorReference.current.codemirror.on("change", () => {
setContent(editorReference.current?.value() || "");
});
}
return () => {
if (editorReference.current) {
try {
editorReference.current.cleanup();
editorReference.current.toTextArea();
} catch (error) {
console.warn("EasyMDE cleanup error:", error);
}
editorReference.current = null;
}
};
}, []);
3.ポイント
- SimpleMDEでは、onChangeをコンポーネント側に渡していましたが、EasyMDEではCodemirrorのchangeイベントで同期する
- React stateと同期することで、モーダルプレビューやフォームの送信時に常に最新の内容を扱うことができる
4.EasyMDEへの移行で得られるメリット
- 表示バグの解消
SimpleMDEで起きていたparentNode関連のレンダリング崩れがほぼ解消される - TypeScriptの型安全性向上
EasyMDEは公式の型定義があり、補完や型チェックが効く - Reactとの統合が安定
useRef+useEffectで初期化・破棄を管理するため、二重のレンダリングやメモリリークの心配が少ない