우선 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>
)
}
이렇게 사용해주면 된다.
기존에 백엔드에서 이미지들을 클라우드에 업로드했다면, 이 이미지들은 하나의 배열에 담겨 문자열 형태로 DB에 저장되었을 것이다. ('["https...., https...."]')과 같이.
그래서 이걸 React에서 배열로 사용하려고 접근하면, 그냥 [이 대괄호 여는 부분이 첫번째 인덱스가 된다.
즉, 문자열로 저장된 겉보기에만 배열인것이다.
그래서 이걸 배열로 바꾸려면
JSON.parse(imageUrlsString);
JSON.parse를 사용해서 배열로 바꿔주면 된다.
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)} />
를 해주면 된다.