feat(editor): 添加支持服务端渲染的编辑器组件

fixbug
钟良源 4 months ago
parent 94ba3bae4a
commit cd9fce74b5

@ -0,0 +1,69 @@
'use client';
import React, { useEffect, useRef, useState } from 'react';
import type { Editor as ToastEditor } from '@toast-ui/react-editor';
import '@toast-ui/editor/dist/toastui-editor.css';
import { isSSR } from '@/utils/is';
interface EditorSectionProps {
initialContent?: string;
}
// 创建一个 Viewer 组件用于服务端渲染
const EditorViewer: React.FC<{ content: string }> = ({ content }) => {
const viewerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!isSSR && viewerRef.current) {
// 在客户端激活时,动态加载 Viewer 并渲染内容
import('@toast-ui/editor/dist/toastui-editor-viewer').then((module) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const { Viewer } = module;
new Viewer({
el: viewerRef.current!,
initialValue: content || ''
});
}).catch((error) => {
console.error('Failed to load Toast UI Viewer:', error);
});
}
}, [content]);
// 服务端直接渲染 HTML 内容
return <div ref={viewerRef} dangerouslySetInnerHTML={{ __html: content || '' }} />;
};
export default function EditorSection({ initialContent }: EditorSectionProps) {
const [isClient, setIsClient] = useState(false);
const editorRef = useRef<typeof ToastEditor | null>(null);
useEffect(() => {
if (!isSSR) {
setIsClient(true);
// 动态导入编辑器组件
import('@toast-ui/react-editor').then((module) => {
editorRef.current = module.Editor;
}).catch((error) => {
console.error('Failed to load Toast UI Editor:', error);
});
}
}, []);
// 在服务端或组件未加载完成时,使用 Viewer 模式显示内容
if (!isClient || !editorRef.current) {
return (
<div className="mt-8">
<EditorViewer content={initialContent || ''} />
</div>
);
}
const DynamicEditor = editorRef.current;
return (
<div className="mt-8">
<DynamicEditor initialValue={initialContent} initialEditType="markdown" />
</div>
);
}
Loading…
Cancel
Save