ReactQuill 에러 해결 기록

augusstt·2023년 3월 17일
0

Project Error

목록 보기
1/4

blog_ag 프로젝트를 진행하며 생겼던 ReactQuill 관련 에러 및 해결을 기록한 글입니다.

blog_ag 프로젝트 코드 바로가기

프로젝트 제작 중, 리액트의 텍스트 에디터 라이브러리인 react-quill을 사용하였다. 이 라이브러리의 기능 중 하나인 이미지 삽입에 대하여, 사이즈 조절이 되지 않는 문제점을 quill-image-resize를 이용하여 해결하려 했지만 잘 되지 않아 등록한 이슈이다.

사용 라이브러리

  1. React-Quill
    • npm install react-quill
    • version : "^2.0.0"
  2. quill-image-resize
    • npm install quill-image-resize-module-ts
    • version : "^3.0.3"

Error Code

src/components/textEditor.tsx

import dynamic from "next/dynamic";
import ReactQuill from "react-quill";
import hljs from "highlight.js/lib/core";
import javascript from "highlight.js/lib/languages/javascript";
import python from "highlight.js/lib/languages/python";
import typescript from "highlight.js/lib/languages/typescript";
import c from "highlight.js/lib/languages/c";
import ImageResize from. "quill-image-resize"

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

hljs.registerLanguage("javascript", javascript);
hljs.registerLanguage("python", python);
hljs.registerLanguage("typescript", typescript);
hljs.registerLanguage("c", c);

const modules = {
  syntax: {
    highlight: (text: any) => hljs.highlightAuto(text).value,
  },
  toolbar: [
    [{ header: [1, 2, false] }, { header: "2" }, { font: [String] }],
    [{ size: [String] }],
    ["bold", "italic", "underline", "strike", "blockquote"],
    [
      { list: "ordered" },
      { list: "bullet" },
      { indent: "-1" },
      { indent: "+1" },
    ],
    ["link", "image", "video", "code-block"],
    ["clean"],
  ],
};

const formats = [
  "header",
  "font",
  "size",
  "bold",
  "italic",
  "underline",
  "strike",
  "blockquote",
  "list",
  "bullet",
  "indent",
  "link",
  "image",
  "video",
  "code-block",
];

const TextEditor = (props: any) => {
  const { content, setContent } = props;
  return (
    <Quill_NoSSR
      modules={modules}
      formats={formats}
      theme={"snow"}
      value={content}
      placeholder={"Please Write a Content!"}
      onChange={(content, delta, source, editor) =>
        setContent(editor.getHTML())
      }
    />
  );
};
export default TextEditor;

Error 1

우선 위의 코드에서 ImageResize 모듈을 등록하기 위해

Quill_NoSSR.register("modules/ImageResize, ImageResize")

라는 코드를 작성하게 되면, Quill_NoSSR에는 register라는 property가 없다는 에러 메시지가 출력된다.
이 문제를 해결하기위해 수많은 구글링을 실시했지만, 딱히 참고할만한 레퍼런스가 존재하지 않았다.
알고보니, 내가 위에서 선언한 Quill_NoSSR이라는 변수는 Next의 dynamic import를 통하여 가져온 변수이기 때문에, Quill 또는 ReactQuill같은 라이브러리 컴포넌트와 달리 register라는 property가 존재 하지 않았던 것이다.

따라서, dynamic import를 실시하는 위치를 바꿔주면 자연스럽게 해결 될 것이라는 생각이 들어, 현재 textEditor 컴포넌트에서 import 하던것을, textEditor를 자식으로 가지고있는 컴포넌트에서 실시하기로 하였다.

Error 2

quill의 ImageResize 모듈 적용시 발생한 에러이다.

addRange(): The given range isn't in document.


Error 1 - Resolving Code

src/components/textEditor.tsx

import ReactQuill from "react-quill";
import hljs from "highlight.js/lib/core";
import javascript from "highlight.js/lib/languages/javascript";
import python from "highlight.js/lib/languages/python";
import typescript from "highlight.js/lib/languages/typescript";
import c from "highlight.js/lib/languages/c";
import ImageResize from. "quill-image-resize"


const modules = {
  syntax: {
    highlight: (text: any) => hljs.highlightAuto(text).value,
  },
  toolbar: [
    [{ header: [1, 2, false] }, { header: "2" }, { font: [String] }],
    [{ size: [String] }],
    ["bold", "italic", "underline", "strike", "blockquote"],
    [
      { list: "ordered" },
      { list: "bullet" },
      { indent: "-1" },
      { indent: "+1" },
    ],
    ["link", "image", "video", "code-block"],
    ["clean"],
  ],
};

const formats = [
  "header",
  "font",
  "size",
  "bold",
  "italic",
  "underline",
  "strike",
  "blockquote",
  "list",
  "bullet",
  "indent",
  "link",
  "image",
  "video",
  "code-block",
];

const TextEditor = (props: any) => {
  const { content, setContent } = props;
  return (
    <ReactQuill
      modules={modules}
      formats={formats}
      theme={"snow"}
      value={content}
      placeholder={"Please Write a Content!"}
      onChange={(content, delta, source, editor) =>
        setContent(editor.getHTML())
      }
    />
  );
};
export default TextEditor;
src/pages/post/index.tsx

import dynamic from "next/dynamic";

// TextEditor를 자식으로 가지는 컴포넌트에 대하여 dynamic import를 실시한다.
const TextEditor = dynamic(() => import("../../components/textEditor"), {
  ssr: false,
});
export default function Post() {

  const [content, setContent] = useState("");

  return (
    <>
        <div className="col-lg-3 col-md-6 text-center">
          <TextEditor content={content} setContent={setContent} />
        </div>
    </>
  );
}

위의 코드처럼 TextEditor를 자식으로 가지는 컴포넌트에 대하여 dynamic import를 실시하고, textEditor 컴포넌트에서는 ReactQuill을 사용하여 컴포넌트를 구성하였다.

이렇게 코드를 작성함으로써, ImageResize 같은 Quill 관련 라이브러리를 register 할 수 있게 되었다.

Error 2 - Resolving Code

src/components/textEditor.tsx

const modules = useMemo(() => {
    return {
      syntax: {
        highlight: (text: any) => hljs.highlightAuto(text).value,
      },
      toolbar: [
        [{ header: [1, 2, false] }, { header: "2" }, { font: [String] }],
        [{ size: [String] }],
        ["bold", "italic", "underline", "strike", "blockquote"],
        [
          { list: "ordered" },
          { list: "bullet" },
          { indent: "-1" },
          { indent: "+1" },
        ],
        ["link", "image", "code-block"],
        ["clean"],
      ],
      ImageResize: { modules: ["Resize"] },
    };
  }, []);

해당 에러에 대하여 구글링해보니, 정의된 modules들이 렌더링마다 매번 생성되고 있기 때문에 발생한 에러라고 한다.
따라서, 기존에 그냥 선언하였던 modules를 useMemo Hook을 이용하여 선언해주면 해결된다..

profile
https://augusstt-note.gitbook.io/aug-note 로 블로그 이전했습니다!

0개의 댓글