ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [next.js] react-quill 에디터 값을 출력하기 (feat. dangerouslySetInnerHTML )
    FrontEnd/Next.js 2024. 1. 31. 22:20
    import 'react-quill/dist/quill.snow.css';
    import { EditorProvideProps } from '../new/new-types';
    
    
    // 중간 생략 
    
    <ReactQuill
        value={field.value}
        onChange={field.onChange}
        modules={quillModules}
        theme="snow"
        className="h-[20rem] md:h-[30rem]"
    />

    ReactQuill에 입력한 데이터 value는 html 요소를 string 형태로 받아와짐

    (++참고) next.js에서 ReactQuill 컴포넌트를 사용할려면 dynamic으로 import 해야함. (window로 정의 되어 있는데 next는 서버 측에서 작동하니 아래처럼 dynamic으로 받아오면서 ssr:false 넣어주기. + useMemo를 하지 않으면 렌더링 될 때마다 변경되어보림)

    const ReactQuill = useMemo(
     () => dynamic(() => import('react-quill'), { ssr: false }),
    [ ] );

    현재 react-quill 스타일링은 import 'react-quill/dist/quill.snow.css' 에서 받아 온 것.

    이후 다른 컴포넌트(or 페이지)에서 에디터에 입력했던 value를 보여주는 방법은 

    div 태그의 dangerouslySetInnerHTML을 이용하는 것이다.

    속성명에서 알 수 있듯이 html 자체를 보여줌으로 보안상 dangerously하므로 Dompurify을 사용한다.(요건 xss 공격 방어에도 쓰이는 스크립트를 문자열로 치환스) 

    ++ 해당 value를 보여줄려는 컴포넌트에서 import 'react-quill/dist/quill.snow.css' 을 해주지 않으면 react-quill 에디터에서 입력했던 스타일링들(size, color 등등)이 적용 안 될 수 있다.

    import 'react-quill/dist/quill.snow.css' 이후 <div classname ="view ql-editor" /> 를 해주는 것으로 해결스

    import React from 'react';
    import 'react-quill/dist/quill.snow.css';
    import DOMPurify from 'dompurify';
    interface PostContentProps {
        content: string;
        like: number;
    }
    
    export const PostContent = ({ content, like }: PostContentProps) => {
        console.log(content);
        return (
            <div className="space-y-5">
                <div
                    className="view ql-editor"
                    dangerouslySetInnerHTML={{
                        __html: DOMPurify.sanitize(content),
                    }}
                    style={{
                        marginTop: '30px',
                        overflow: 'hidden',
                        whiteSpace: 'pre-wrap',
                    }}
                />
                <div className="text-center">{like}</div>
            </div>
        );
    };
Designed by Tistory.