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
Don't look back, just look forward and study 💻

0개의 댓글