You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中动态导入组件使用useRef获取实例异常问题求助

问题解决:Next.js动态导入Toast UI Editor后ref获取异常

问题原因

你的代码里存在两个核心问题:

  1. useImperativeHandle返回了嵌套的current结构,导致父组件的ref指向了一个包含current属性的对象,而非直接的编辑器实例
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 02:17:05