使用 Next.js 的 React-quill 历史

React-quill history with Next.js

提问人:Vladislav 提问时间:10/4/2023 更新时间:10/5/2023 访问量:60

问:

我正在尝试使用历史记录模块(撤消和重做按钮)将 Quill 编辑器添加到我的 Next.js 项目中。我必须使用动态导入,否则,我收到未定义文档的错误。

下面是我的代码。它有效,但我有两个问题:

  1. 撤消/重做按钮的图标丢失。有一些例子,人们这样做,然后分配自定义图标,但是我如何使用动态导入访问 ReactQuill.Quill?icons = ReactQuill.Quill.import("ui/icons");

  2. 当我尝试为“撤消”和“重做”或任何其他按钮实际添加自定义处理程序时,编辑器只是从页面中消失,而不会在控制台中显示任何错误

import dynamic from "next/dynamic";
const ReactQuill = dynamic(
  async () => {
    const { default: RQ } = await import("react-quill");
    return ({ forwardedRef, ...props }) => <RQ ref={forwardedRef} {...props} />;
  },
  {
    ssr: false,
  }
);
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();

export default function Editor({ title, body = "" }) {
  const quillRef = useRef(false);
  const text = title ? "# " + title + "\n\n" + body : body;
  const initialHtml = converter.makeHtml(text);
  const [html, setHtml] = useState(initialHtml);

  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: {},
        },
      }}
    />
  );
}
reactjs next.js react-quill

评论


答:

0赞 Vladislav 10/5/2023 #1

发布工作代码,以防有人遇到同样的问题。

import dynamic from "next/dynamic";
const ReactQuill = dynamic(
  async () => {
    const { default: RQ } = await import("react-quill");
    const Quill = RQ.Quill;
    const icons = Quill.import("ui/icons");
    icons["undo"] = `<svg viewbox="0 0 18 18">
        <polygon class="ql-fill ql-stroke" points="6 10 4 12 2 10 6 10"></polygon>
        <path class="ql-stroke" d="M8.09,13.91A4.6,4.6,0,0,0,9,14,5,5,0,1,0,4,9"></path>
      </svg>`;
    icons["redo"] = `<svg viewbox="0 0 18 18">
        <polygon class="ql-fill ql-stroke" points="12 10 14 12 16 10 12 10"></polygon>
        <path class="ql-stroke" d="M9.91,13.91A4.6,4.6,0,0,1,9,14a5,5,0,1,1,5-5"></path>
      </svg>`;
    return ({ forwardedRef, ...props }) => <RQ ref={forwardedRef} {...props} />;
  },
  {
    ssr: false,
  }
);
import showdown from "showdown";
import "react-quill/dist/quill.snow.css";
import { useState, useMemo, useRef } from "react";
import styles from "./Editor.module.css";

const converter = new showdown.Converter();

export default function Editor({ title, body = "" }) {
  const quillRef = useRef(false);
  const text = title ? "# " + title + "\n\n" + body : body;
  const initialHtml = converter.makeHtml(text);
  const [html, setHtml] = useState(initialHtml);

  function undo() {
    if (quillRef.current) {
      const myEditor = quillRef.current.getEditor();
      return myEditor.history.undo();
    }
  }

  function redo() {
    if (quillRef.current) {
      const myEditor = quillRef.current.getEditor();
      return myEditor.history.redo();
    }
  }

  const modules = useMemo(
    () => ({
      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"],
        ],
        handlers: {
          undo: undo,
          redo: redo,
        },
      },
    }),
    []
  );

  return (
    <ReactQuill
      forwardedRef={quillRef}
      theme="snow"
      value={html}
      onChange={setHtml}
      modules={modules}
    />
  );
}