简体   繁体   English

Nextjs:如何仅在客户端渲染时将 quill-blot-formatter 注册到动态导入的 react-quill?

[英]Nextjs: How to register the quill-blot-formatter to dynamically imported react-quill on client side rendering only?

I am importing react-quill dynamically on the client side only using ssr: false .我仅使用ssr: false在客户端动态导入react-quill My functional component which is working fine, I want to add the quill-blot-formatter package to the modules part of my quill component.我的功能组件运行良好,我想将 quill quill-blot-formatter package 添加到我的 quill 组件的modules部分。

My first roadblock is, I can't register this quill-blot-formatter with Quill as it shows:我的第一个障碍是,我无法使用Quill注册这个quill-blot-formatter ,因为它显示:

ServerError
ReferenceError: document is not defined

This page is client rendered, therefore I don't understand where this error is coming from!此页面是客户端呈现的,因此我不明白此错误来自何处!

This is my code:这是我的代码:

import dynamic from "next/dynamic";
import BlotFormatter from "quill-blot-formatter";

const QuillNoSSRWrapper = dynamic(import('react-quill'), {
    ssr: false,
    loading: () => <p>Loading...</p>,
})

Quill.register("modules/blotFormatter", BlotFormatter);

Here, I don't understand how to bring Quill out of react-quill now that it's being imported dynamically.在这里,我不明白如何将Quillreact-quill中取出,因为它是动态导入的。 Therefore, I think that Quill.register isn't working.因此,我认为Quill.register不起作用。 Now, how do I register quill-blot-formatter with react-quill ?现在,如何使用react-quill注册quill-blot-formatter Following the Next.js example with react-quill , I am not even importing react-quill as ReactQuill as is the default export in the package.按照带有 react-quill 的 Next.js 示例,我什至没有像ReactQuill中的默认导出那样将 react-quill 导入为 ReactQuill。

Then I declared the blotFormatter module like this.然后我这样声明blotFormatter模块。

const modules = {
    blotFormatter: {},  // here
    toolbar: [
        [{header: '1'}, {header: '2'}, {font: []}],
        [{size: []}],
        ...
    ],
}

const formats = ['header','font','size','bold','italic','underline',...]

And used in the render() method like this:并像这样在render()方法中使用:

export default function NewContent() {
    ...
    render(
        <QuillNoSSRWrapper
            className={styles.quillTextArea}
            id="quilleditor"
            modules={modules}
            formats={formats}
            theme="snow"
            onChange={handleTextChange}
            readOnly={false}
        />
    );
}

So far, this QuillNoSSRWrapper child component is doing it's job fine, but, how do I use the quill-blot-formatter in it's formats ?到目前为止,这个QuillNoSSRWrapper子组件工作正常,但是,我如何在它的formats中使用quill-blot-formatter

UPDATE更新

You don't need another useEffect to register module you can do it when you importing ReactQuill.您不需要另一个 useEffect 来注册模块,您可以在导入 ReactQuill 时进行注册。

const ReactQuill = dynamic(
  async () => {
    const { default: RQ } = await import("react-quill");
    const { default: BlotFormatter } = await import("quill-blot-formatter");
    RQ.Quill.register("modules/blotFormatter", BlotFormatter);
    return function forwardRef({ forwardedRef, ...props }) {
      return <RQ ref={forwardedRef} {...props} />;
    };
  },
  {
    ssr: false,
  }
);

With this code you importing ReactQuill, register you module and pass ref that you can use later see details below .使用此代码,您可以导入 ReactQuill,注册您的模块并传递您稍后可以使用的 ref,请参阅下面的详细信息。 So with this code you now don't need any state. Additionally you can add custom loading function to dynamic details here .因此,使用此代码,您现在不需要任何 state。此外,您可以在此处将自定义加载 function 添加到动态详细信息


After one day of searching i found the solution.经过一天的搜索,我找到了解决方案。 First of all you import dynamic ReactQuill.首先你导入动态 ReactQuill。

import dynamic from 'react/dynamic'
const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });

Or if you want to pass ref like this或者如果你想像这样传递 ref

const ReactQuill = dynamic(
  async () => {
    const { default: RQ } = await import("react-quill");
    // eslint-disable-next-line react/display-name
    return ({ forwardedRef, ...props }) => <RQ ref={forwardedRef} {...props} />;
  },
  {
    ssr: false,
  }
);

And then you can use ref like this <ReactQuill... forwardedRef={quillRef}/>然后你可以像这样使用 ref <ReactQuill... forwardedRef={quillRef}/>

So then after you imported ReactQuill on client side you need to register module i found this solution here it's looks strange and i had no time to improve it but it's work.因此,在客户端导入 ReactQuill 之后,您需要注册模块,我在这里找到了这个解决方案,它看起来很奇怪,我没有时间改进它,但它确实有效。 Here the code.这是代码。

  const loadQuill = async () => {
    return new Promise(async (resolve, reject) => {
      const Quill = await require("react-quill").Quill;
      const BlotFormatter = (await import("quill-blot-formatter")).default;
      resolve({ Quill, BlotFormatter });
    })
      .then(({ Quill, BlotFormatter }) => {
        Quill.register("modules/blotFormatter", BlotFormatter);
        return;
      })
      .then((value) => {
        setEnableEditor(true);
      });
  };

  useEffect(() => {
    loadQuill();
  }, []);

This code will execute on client side end register module.此代码将在客户端端注册模块上执行。 Also as you can see you need to declarate state enableEditor.同样如您所见,您需要声明 state enableEditor。 And render ReactQuill only when enableEditor is true并且仅在 enableEditor 为真时渲染 ReactQuill

{enableEditor && <ReactQuill ... />}

Looks bit wierd so maybe I will update it later看起来有点奇怪,所以也许我稍后会更新它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM