웹에디터 (ReactQuill) 적용과 주의점

SongNoin·2021년 10월 13일
1
post-thumbnail

웹에디터 (ReactQuill) 적용하기

ReactQuill 주소

https://www.npmjs.com/package/react-quill

ReactQuill 이란?

웹에디터 라이브러리 중 하나로써, 줄바꿈, 글꼴, 글자색 심지어 사진 등을 쉽게 적용해 줄 수있다.

ReactQuill 를 쓰는 이유

textarea안에서 줄바꿈을 해줘도 값이 들어가는건 한줄로 들어간다.
또한 사용자에게 글꼴, 글자색등 다양한 선택권을 주기위해서 필요하다

📔 결과물

💻 코드리뷰

market-write.styles.ts

  • Next JS는 기본적으로 서버 사이드렌더링을 지원하게 지원하게 되는데
    서버로부터 웹페이지를 렌더링하는 시점에서는 window 또는 document object를 선언하기 전이기에
    document가 선언되지 않았다는 에러를 발생하게 된다.

  • 이 문제를 해결하기 위해서 ReactQuillimport하게 되는 시점을
    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 라이브러리가 있다.
    Dompurifysanitize기능을 활용한다면 이를 막아 줄 수 있다.

  • process.browser 을 써준 이유는 서버에서 처리할 내용을 적어주기 위함이다.
    주로 localStorage를 사용할때 많이 쓴다.
import Dompurify from "dompurify";
...
{process.browser && (
  <Contents
    dangerouslySetInnerHTML={{
      __html: Dompurify.sanitize(
        props.data?.fetchUseditem.contents
      ),
        }}
    />
)}
...

여기까지 작성을 잘 했다면 ReactQuill을 잘 활용 할 수 있다.

단순 라이브러리 사용 뿐만 아니라 전체 구조적인 시야를 넓힐 수 있는 기회였던 것 같다!

0개의 댓글