본문 바로가기
SPA/Next

[Next] Editor 사용하기 (2) - Toast UI

by J4J 2022. 1. 7.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 Toast UI Editor 사용하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

들어가기에 앞서 다음 글도 참고해보시면 좋을 것 같습니다.

 

 

 

 

앞선 글에서 언급했듯이 Editor를 사용해보기 위해 다음과 같이 총 3개의 패키지를 찾을 수 있었습니다.

 

  • react-quill
  • @toast-ui/react-editor
  • react-draft-wysiwyg

 

 

 

이번에는 이들 중 현재 사용했을 때 두 번째로 괜찮다고 생각한 @toast-ui/react-editor에 대해 소개를 해보겠습니다.

 

간단한 사용 방법과 제가 경험할 수 있었던 특징에 대해 적어보겠습니다.

 

 

 

이미지 서버 설정

 

먼저 이미지를 업로드하고 불러올 수 있는 서버가 필요한데 서버 설정과 관련된 것은 위에 링크를 걸어둔 React Quill을 참고해주시길 바랍니다.

 

 

 

Toast UI 사용 방법

 

[ 1. 패키지 설치 ]

 

$ npm install @toast-ui/react-editor @toast-ui/editor-plugin-color-syntax

 

 

반응형

 

 

[ 2. Editor 컴포넌트 생성 ]

 

/components 위치에 editor.tsx파일을 생성하여 다음과 같이 Editor를 만들어보겠습니다.

 

import * as React from 'react';
import axios from 'axios';
import styled from 'styled-components';
import { NextPage } from 'next';

import { Editor as ToastEditor } from '@toast-ui/react-editor';
import '@toast-ui/editor/dist/toastui-editor.css';

import colorSyntax from '@toast-ui/editor-plugin-color-syntax';
import 'tui-color-picker/dist/tui-color-picker.css';
import '@toast-ui/editor-plugin-color-syntax/dist/toastui-editor-plugin-color-syntax.css';

interface IEditor {
    htmlStr: string;
    setHtmlStr: React.Dispatch<React.SetStateAction<string>>;
}

const Editor: NextPage<IEditor> = ({ htmlStr, setHtmlStr }) => {

    const editorRef = React.useRef<ToastEditor>(null);

    // Editor Change 이벤트
    const onChangeEditor = () => {
        if(editorRef.current) {
            setHtmlStr(editorRef.current.getInstance().getHTML());
        }
    }

    React.useEffect(() => {
        if(editorRef.current) {
            // 전달받은 html값으로 초기화
            editorRef.current.getInstance().setHTML(htmlStr);

            // 기존 이미지 업로드 기능 제거
            editorRef.current.getInstance().removeHook('addImageBlobHook');
            // 이미지 서버로 데이터를 전달하는 기능 추가
            editorRef.current.getInstance().addHook('addImageBlobHook', (blob, callback) => {
                (async () => {
                    const formData = new FormData();
                    formData.append("multipartFiles", blob);

                    const res = await axios.post('http://localhost:8080/uploadImage', formData);

                    callback(res.data, "input alt text");
                  })();
        
                return false;
            });
        }
    }, [])

    // Editor에 사용되는 plugin 추가
    const plugins = [
        colorSyntax, // 글자 색상 추가
    ]

    return (
        <CustomReactQuill
            initialValue=""
            previewStyle="vertical"
            initialEditType="wysiwyg"
            useCommandShortcut={true}
            ref={editorRef}
            plugins={plugins}
            onChange={onChangeEditor}
        />
    )
}

export default Editor;

// style
const CustomReactQuill = styled(ToastEditor)`
    height: 300px;
`

 

 

 

[ 3. Editor 사용하는 파일 작성 ]

 

위에 만들어 둔 Editor 컴포넌트를 불러와 사용하는 코드를 index.tsx에 작성해보겠습니다.

 

작성하기 전 주의해야 될 부분은 Editor 컴포넌트를 불러올 때 dynamic을 이용하여 ssr을 false로 설정해줘야 합니다.

 

사용해본 다른 Editor들도 동일하게 설정을 해줘야 하기 때문에 참고하시면 될 것 같습니다.

 

import * as React from 'react';
import dynamic from 'next/dynamic';
import styled from 'styled-components';
import { NextPage } from 'next';

const Editor = dynamic(() => import('../components/editor'), { ssr: false }); // client 사이드에서만 동작되기 때문에 ssr false로 설정

const Index: NextPage = () => {
    // state
    const [htmlStr, setHtmlStr] = React.useState<string>('');

    // ref
    const viewContainerRef = React.useRef<HTMLDivElement>(null);

    // useEffect
    React.useEffect(() => {
        if(viewContainerRef.current) {
            viewContainerRef.current.innerHTML = '<h2>html 코드를 이용하여 만들어지는 View입니다.</h2>'
            viewContainerRef.current.innerHTML += htmlStr;
        }
    }, [htmlStr])

    return (
        <>
            <EditorContainer>
                <Editor htmlStr={htmlStr} setHtmlStr={setHtmlStr} />
            </EditorContainer>

            <Contents.Container>
                <Contents.HtmlContainer>
                    <h2>Editor를 통해 만들어진 html 코드입니다.</h2>
                    {htmlStr}
                </Contents.HtmlContainer>

                <Contents.ViewContainer ref={viewContainerRef} />
            </Contents.Container>
        </>
    );
};

export default Index;

// style
const EditorContainer = styled.div`
    width: 800px;
    height: 400px;

    margin: 0 auto;
`;

const Contents = {
    Container: styled.div`
        width: 1200px;
        
        margin: 0 auto;

        display: flex;
        gap: 40px;

        & > div {
            width: 600px;

            padding: 16px;

            box-sizing: border-box;

            line-break: anywhere;
        }
    `,

    HtmlContainer: styled.div`
        border: 2px solid orange;
    `,

    ViewContainer: styled.div`
        border: 2px solid olive;

        & pre {
            margin: 0;
        }

        // quill에서 코드 블럭을 사용한 경우
        .toastui-editor-ww-code-block {
            background-color: #f4f7f8;
            padding: 18px;
            margin: 2px 0 8px;
        }
    `,
}

 

 

728x90

 

 

테스트

 

코드를 작성하고 실행해보면 다음과 같은 화면을 확인할 수 있습니다.

 

실행 결과 - WYSIWYG

 

 

 

상위에 있는 것은 Editor, 좌측 하단에 있는 것은 Editor로 만들어진 html 코드, 우측 하단은 html 코드로 화면을 구성했을 때 보이는 모습입니다.

 

 

 

또한 Toast UI는 WYSIWYG로 불리는 일반 편집기뿐만 아니라 Markdown도 제공해줍니다.

 

WYSIWYG에서 위와 같이 보이는 상태를 Markdown로 변경하면 다음과 같습니다.

 

실행 결과 - Markdown

 

 

 

특징

 

Editor를 찾아보기 전에 원했던 Editor 기능들은 다음과 같습니다.

 

  • 텍스트 정렬
  • 텍스트 색깔 지정
  • 이미지 업로드
  • 이미지 사이즈 조절
  • XSS 방지
  • 기타 등등...

 

 

 

Toast UI는 이런 기능들의 대부분을 지원해주고 있습니다.

 

이미지 업로드뿐만 아니라 plugin을 등록하면 텍스트 색깔도 사용해줄 수 있습니다.

 

하지만 가장 충격적인 건 텍스트 정렬을 할 수 없었습니다.

 

제가 못 찾는 것일 수도 있기에 아시는 분은 댓글 달아주시면 감사드리겠습니다.

 

 

 

 

이 외에는 사실 현재 가장 마음에 들었다고 한 React Quill 이상의 기능들을 제공해주는 것 같습니다.

 

사용 방법도 어렵지 않다고 느껴졌고 또한 스타일을 클래스로 지정해주고 업로드된 이미지를 드래그해서도 카피시켜주는 등의 기능들을 확인할 수 있었습니다.

 

 + 테이블 삽입 기능

 + Task 기능

 

 

 

그럼에도 불구하고 가장 괜찮았다고 생각한 것이 React Quill인 이유는 단순하게 텍스트 정렬 때문입니다.

 

왜냐하면 저에게 우선순위가 높은 기능 중에 하나이기 때문에 다른 분들에게는 Toast UI가 더 매력적으로 느끼셨을 수도 있을 것 같습니다.

 

만약 텍스트 정렬하는 기능만 추가할 수 있다면 저도 Toast UI를 제가 사용해 본 에디터 중 가장 괜찮았던 걸로 선택할 수 있다고 생각합니다.

 

 

 

 

 

 

이상으로 Toast UI Editor 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글