Next.js中动态导入组件使用useRef获取实例异常问题求助
问题解决:Next.js动态导入Toast UI Editor后ref获取异常
问题原因
你的代码里存在两个核心问题:
useImperativeHandle返回了嵌套的current结构,导致父组件的ref指向了一个包含current属性的对象,而非直接的编辑器实例- Next.js动态加载组件时,初始渲染阶段
editorRef.current会指向dynamic组件的内部实例(包含retry方法,用于加载失败重试),而非真正的Toast UI Editor实例
修复方案
1. 修改WysiwygEditor组件
调整useImperativeHandle的返回逻辑,直接暴露编辑器实例或所需方法,避免嵌套结构:
import dynamic from "next/dynamic"; import React, { useImperativeHandle, useRef, forwardRef } from "react"; import "@toast-ui/editor/dist/toastui-editor.css"; // 动态导入Editor,添加加载状态提示(可选) const Editor = dynamic(() => import("@toast-ui/react-editor").then((mod) => mod.Editor), { ssr: false, loading: () => <div>加载编辑器中...</div> }); const WysiwygEditor = forwardRef((props, ref) => { const editorRef = useRef(null); // 直接暴露编辑器实例及常用方法 useImperativeHandle(ref, () => ({ // 获取底层编辑器核心实例 getCoreInstance: () => editorRef.current?.getInstance(), // 快速获取HTML内容 getHtmlContent: () => editorRef.current?.getInstance().getHtml(), // 直接返回组件实例(如果需要操作组件本身) componentInstance: editorRef.current }), [editorRef.current]); return ( <Editor ref={editorRef} height="400px" initialEditType="wysiwyg" previewStyle="vertical" hideModeSwitch={true} useCommandShortcut={true} {...props} /> ); }); export default WysiwygEditor;
2. 修改CreatePost组件
通过暴露的方法获取真实编辑器实例,避免直接访问未初始化的ref:
import WysiwygEditor from "../wysiwygEditor"; import { useRef } from "react"; const CreatePost = () => { const editorRef = useRef(null); const printRefCurrent = () => { // 获取真实编辑器核心实例 const coreEditor = editorRef.current?.getCoreInstance(); console.log(coreEditor); // 也可以直接打印暴露的方法集合 // console.log(editorRef.current); }; return ( <> <WysiwygEditor ref={editorRef} /> <button onClick={printRefCurrent}>Click</button> </> ); }; export default CreatePost;
关键说明
- Toast UI的React Editor组件需要通过
getInstance()方法获取底层的编辑器核心实例,组件本身的ref只是React组件实例 - 动态加载组件时,务必通过可选链(
?.)处理未加载完成的情况,避免控制台报错 - 不要在
useImperativeHandle中返回嵌套的current对象,直接返回目标实例或方法集合即可
内容的提问来源于stack exchange,提问作者Sein kim
相关产品推荐
相关产品推荐

