diff --git a/src/components/EditorSection/index.tsx b/src/components/EditorSection/index.tsx new file mode 100644 index 0000000..a465c7b --- /dev/null +++ b/src/components/EditorSection/index.tsx @@ -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(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
; +}; + +export default function EditorSection({ initialContent }: EditorSectionProps) { + const [isClient, setIsClient] = useState(false); + const editorRef = useRef(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 ( +
+ +
+ ); + } + + const DynamicEditor = editorRef.current; + + return ( +
+ +
+ ); +} \ No newline at end of file