Quill 정리

이찬영·2025년 2월 1일

우선 Quill라이브러리를 사용하려면
npm install quill 을 설치해준뒤,

import Quill from 'quill';
import 'quill/dist/quill.snow.css';
import {useEffect, useRef} from 'react';

function QuillComponent({setArticleValues}) {
	const quillRef = useRef(null); // quill 에디터가 생성될 DOM엘리먼트를 참조
  	useEffect(() => {
    	if(!quillRef.current) return;
      
      	const quillInstance = new Quill(quillRef.current, {
        	theme : "snow",
          	modules : {
            	toolbar : [
                	['bold', 'italic', 'underline'],
                  	[{list : "ordered"}, {list : "bullet"}],
                  	["link", "image"]
                ]
            }
        })
        
        
        quillInstance.on("text-change", () => {
        	setArticleValues((prev) => ({
            	...prev,
              	articleContent : quillInstance.root.innerHTML
            }))
        })
    }, [])
  
  return (
  	<div>
    	<div ref={quillRef} />
    </div>
  )
}

이렇게 사용해주면 된다.

문자열로 저장된 이미지URL들

기존에 백엔드에서 이미지들을 클라우드에 업로드했다면, 이 이미지들은 하나의 배열에 담겨 문자열 형태로 DB에 저장되었을 것이다. ('["https...., https...."]')과 같이.
그래서 이걸 React에서 배열로 사용하려고 접근하면, 그냥 [이 대괄호 여는 부분이 첫번째 인덱스가 된다.
즉, 문자열로 저장된 겉보기에만 배열인것이다.
그래서 이걸 배열로 바꾸려면

JSON.parse(imageUrlsString); 

JSON.parse를 사용해서 배열로 바꿔주면 된다.

quill 관련

quill로 저장된 문자열들

quill로 데이터를 DB에 저장하게 되면, innerHTML에 의해 HTML태그들까지 함께 DB에 저장되게 된다. <p>``<br>등과 같이 말이다.
그래서 React에서 데이터를 받아오고, 그 데이터를 문자열 처럼 사용하려면, DOMParser()를 사용하면 된다.

function plainText (html) {
	if(!html) return "";
  	const doc = new DOMParser().parseFromString(html, "text/html");
  	return doc.body.textContent || "";
}

와 같이 함수를 작성해주면, text값만 받아올 수 있다.

또 실제 본문을 (html형태로 저장된 데이터를 html형태 그대로) 보여줘야할땐, HTML태그에 dangerouslySetInnerHTML이란 속성을 부여해주면 된다. 이를 함수로 작성하자면

function createMarkUp (html) {
	return {__html : html};
}

과 같이 객체로 뱉어주면 된다.
그리고, 이것을 사용할 땐, XSS공격에 취약하기 때문에, 라이브러리 중에 <script>태그를 자동으로 삭제시켜버리는 dompurify를 설치해서

import DOMPurify from 'dompurify';

function createMarkUp (html) {
	return {__html : DOMPurify.sanitize(html)};
}

...
...
<div dangerouslySetInnerHTML : {createMarkUp(articleContent)} />

를 해주면 된다.

0개의 댓글