Next.js中集成带History模块的React-Quill遇两大问题求助
Next.js 中 ReactQuill 历史模块图标缺失与自定义处理器问题解决
问题1:撤销/重做按钮图标缺失
动态导入 ReactQuill 时无法直接访问 ReactQuill.Quill,可通过以下两种方式解决:
方法1:动态导入时注册图标
修改动态导入逻辑,同时导入 Quill 核心库并注册默认图标:
const ReactQuill = dynamic( async () => { const { default: RQ } = await import("react-quill"); // 直接导入Quill核心库 const Quill = await import("quill"); // 导入默认图标集 const icons = Quill.import("ui/icons"); // 若需自定义图标,可在此修改(示例:替换撤销图标) // icons.undo = '<svg viewBox="0 0 18 18"><path d="M10.5 1.5v4.5h4.5L9 12l-6-6h4.5V1.5h3z"/></svg>'; // 注册图标 Quill.register("ui/icons", icons, true); return ({ forwardedRef, ...props }) => <RQ ref={forwardedRef} {...props} />; }, { ssr: false } );
方法2:组件挂载后通过Ref设置图标
在组件的 useEffect 中,通过编辑器Ref获取Quill实例,再导入并设置图标:
useEffect(() => { if (quillRef.current) { const quill = quillRef.current.getEditor(); const icons = quill.import("ui/icons"); // 可选:自定义图标 // icons.undo = '<svg>...</svg>'; quill.register("ui/icons", icons, true); // 刷新工具栏 quill.getModule("toolbar").render(); } }, []);
问题2:添加自定义处理器后编辑器消失
直接在 modules.toolbar.handlers 中定义处理器会因Quill实例未初始化导致异常,需通过Ref动态添加处理器:
- 保持
modules中的handlers为空对象:
modules={{ history: { delay: 2000, maxStack: 300, userOnly: true, }, toolbar: { container: [/* 你的工具栏配置 */], handlers: {}, // 留空,后续动态添加 }, }}
- 在
useEffect中动态注册处理器:
useEffect(() => { if (quillRef.current) { const quill = quillRef.current.getEditor(); const toolbarModule = quill.getModule("toolbar"); // 自定义撤销处理器 toolbarModule.addHandler("undo", () => { // 执行默认撤销逻辑 quill.history.undo(); // 添加你的自定义操作 console.log("撤销操作已触发"); }); // 自定义重做处理器 toolbarModule.addHandler("redo", () => { quill.history.redo(); console.log("重做操作已触发"); }); } }, [quillRef.current]);
完整修改后的代码
import dynamic from "next/dynamic"; import showdown from "showdown"; import "react-quill/dist/quill.snow.css"; import { useState, useEffect, useRef } from "react"; import React from "react"; import styles from "./Editor.module.css"; const converter = new showdown.Converter(); // 动态导入ReactQuill并注册图标 const ReactQuill = dynamic( async () => { const { default: RQ } = await import("react-quill"); const Quill = await import("quill"); const icons = Quill.import("ui/icons"); Quill.register("ui/icons", icons, true); return ({ forwardedRef, ...props }) => <RQ ref={forwardedRef} {...props} />; }, { ssr: false } ); export default function Editor({ title, body = "" }) { const quillRef = useRef(null); const text = title ? "# " + title + "\n\n" + body : body; const initialHtml = converter.makeHtml(text); const [html, setHtml] = useState(initialHtml); useEffect(() => { if (quillRef.current) { const quill = quillRef.current.getEditor(); const toolbarModule = quill.getModule("toolbar"); // 自定义撤销处理器 toolbarModule.addHandler("undo", () => { quill.history.undo(); console.log("撤销操作触发"); }); // 自定义重做处理器 toolbarModule.addHandler("redo", () => { quill.history.redo(); console.log("重做操作触发"); }); } }, [quillRef.current]); return ( <ReactQuill forwardedRef={quillRef} theme="snow" value={html} onChange={setHtml} modules={{ history: { delay: 2000, maxStack: 300, userOnly: true, }, toolbar: { container: [ [{ header: [1, 2, 3, 4, 5, 6, false] }], ["bold", "italic", "underline"], [{ list: "ordered" }, { list: "bullet" }], ["link"], ["undo", "redo", "image"], ], handlers: {}, }, }} /> ); }
内容的提问来源于stack exchange,提问作者Vladislav
相关产品推荐
相关产品推荐

