웹에디터 (ReactQuill) 적용하기
ReactQuill 주소
https://www.npmjs.com/package/react-quill
ReactQuill 이란?
웹에디터 라이브러리 중 하나로써, 줄바꿈, 글꼴, 글자색 심지어 사진 등을 쉽게 적용해 줄 수있다.
ReactQuill 를 쓰는 이유
textarea안에서 줄바꿈을 해줘도 값이 들어가는건 한줄로 들어간다.
또한 사용자에게 글꼴, 글자색등 다양한 선택권을 주기위해서 필요하다📔 결과물
💻 코드리뷰
market-write.styles.ts
Next JS
는 기본적으로 서버 사이드렌더링을 지원하게 지원하게 되는데
서버로부터 웹페이지를 렌더링하는 시점에서는window
또는document object
를 선언하기 전이기에
document
가 선언되지 않았다는 에러를 발생하게 된다.
- 이 문제를 해결하기 위해서
ReactQuill
를import
하게 되는 시점을
document
가 선언된 시점이후에 선언할 수 있게 해야한다.
- 그래서 그냥 import해서는 안되고 꼭 아래와 같이
dynamic
을 사용해서import
를 해준다.import dynamic from "next/dynamic"; const ReactQuill = dynamic(() => import("react-quill"), { ssr: false }); ... export const DetailText = styled(ReactQuill)` width: 100%; height: 320px; margin-bottom: 40px; `; ...
💻 market-write.container.tsx
onChange
함수를 선언해준다.ReactQuill
이 비워있으면
<p><br></p>
로 입력이 된 상태이기 때문에 입력값이 있는 상태로 여겨진다.
그래서<p><br></p>
값이 있어도 비워진 상태로 처리하게 한다.function onChangeMyContents(value) { setValue("contents", value === "<p><br></p>" ? "" : value); trigger("contents"); }
modules
를 선언해주면서ReactQuill
의 쓰고싶은 기능들을 설정해준다.
자세한방법은Docs
를 참고하기!const modules = { toolbar: { container: [ [{ header: [1, 2, 3, 4, 5, 6, false] }], [{ font: [] }], [{ align: [] }], ["bold", "italic", "underline", "strike", "blockquote"], [{ list: "ordered" }, { list: "bullet" }, "link"], [ { color: [ "#000000", "#e60000", ... // 원하는 글꼴색 색코드 넣기 "custom-color", ], }, { background: [] }, ], ["image", "video"], ["clean"], ], }, };
💻 market-write.presenter.tsx
onChange
함수와modules
를 넣어준다.<DetailText onChange={props.onChangeMyContents} modules={props.modules} />
이렇게 쓰는건 완료했지만 보여질때에도 신경을 써야한다.
그 이유는 HTML태그들도 같이 보여지기때문이다!
ex)
<p>안녕하세요?</p><br><p>반갑습니다!</p>
💻 market-detail.container.tsx
dangerouslySetInnerHTML 란 ?
이 내용들이 문자열이 아닌, 태그의 기능 그 자체로 인식하게 만들기 위할때 쓰는 태그이다
dangerously
란 단어가 붙은 이유는 이용자가 마음만 먹는다면
직접 백엔드 서버에 관여할 수 있기때문에 조심히 써야하기 때문이다.
- 그래서 이를 방지하기위해
DOMPurify
라이브러리가 있다.
Dompurify
의sanitize
기능을 활용한다면 이를 막아 줄 수 있다.
process.browser
을 써준 이유는 서버에서 처리할 내용을 적어주기 위함이다.
주로localStorage
를 사용할때 많이 쓴다.import Dompurify from "dompurify"; ... {process.browser && ( <Contents dangerouslySetInnerHTML={{ __html: Dompurify.sanitize( props.data?.fetchUseditem.contents ), }} /> )} ...
여기까지 작성을 잘 했다면 ReactQuill을 잘 활용 할 수 있다.
단순 라이브러리 사용 뿐만 아니라 전체 구조적인 시야를 넓힐 수 있는 기회였던 것 같다!