draft.jsやtui-editorに共通して言えることですが、
元々ブラウザでの動作を想定して作られているので、
NextJSなどのSSR環境下ではwindow
、document
などの変数の中身がundefined
になり、動作しなくなります。
インポート方法を変えることでSSRを無効にできるオプションがあります。
dynamic import自体はES2020で導入される構文だとか。
const DraftEditorNoSSR = dynamic<DraftEditorProp>(
() => import('../components/DraftEditor') as any,
{ ssr: false }
)
draft.jsでは再描画した際にカーソルが行の先頭に戻るというバグがあります。
公式リポジトリでは行の最後に移動する対処も議論されていますが、文章の中で編集したくなったらどうするんだ....という声もちらほら。
How to stop DraftJS cursor jumping to beginning of text?
さっさと見切りをつけてToastUI editorに移りました。
そうです、crieitにも採用されているエディタですね。
ただし、Toast UI Editorはrefを使わないと値が取れず、
マウントされていない状態でrefがnullになってしまうことにかなり苦しめられました。
changeイベントがeditorで発火するのでフラグを更新するようにして、外側でrefを使ってデータを取り出すという実装になりました。
それから、画像アップロードをdisabledにしました。
editorコンポーネントを使いまわしたかったので、
表示用の初期値initialValue
と値を更新して外部に渡すsetFunc
をpropsとして与えています。
const DraftEditor = ({ initialValue, setFunc }) => {
const editorRef = createRef<Editor>();
const [changed, setChanged] = useState(false);
useEffect(() => {
if (editorRef.current && changed) {
setFunc(editorRef.current.getInstance().getMarkdown());
console.log("set");
setChanged(false);
}
}, [editorRef.current, changed]);
return (
<div
style={{
width: "100vw",
}}
>
<div>
<Editor
previewStyle="vertical"
toolbarItems={[
"heading",
"bold",
"italic",
"strike",
"divider",
"hr",
"quote",
"ul",
"ol",
"task",
"table",
"link",
"divider",
]}
height="400px"
initialEditType="markdown"
initialValue={initialValue}
ref={editorRef}
hideModeSwitch={true}
events={{
change: (e) => {
setChanged(true);
},
}}
/>
</div>
</div>
);
};
export default DraftEditor;
export type DraftEditorProp = {
initialValue: string;
setFunc: Dispatch<any>;
};
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント