[개발일지] Toast UI Editor 적용

남현우·2022년 11월 20일
0
post-thumbnail
post-custom-banner

Toast UI Editor

커뮤니티를 만들다보니 Text Editor가 필요해 몇 에디터를 비교해봤다.
무엇보다 사용성에 초점을 두어 내가 사용하기 편한 에디터를 찾게 되었는데,
다름아닌 Toast UI Editor를 선택하게 되었다.

Toast UI Editor는 리액트, 뷰, Vanilla JS를 지원하는 에디터로 Markdown 에디터임에도,
WYSIWYG 에디터를 동시에 지원한다는 장점이 있다.
또, 마크다운의 프리뷰와 기본 뷰어도 제공해 개발에도, 사용에도 용이하다고 판단했다.

Toast UI Editor 적용

에디터를 typescirpt와 yarn berry를 이용한 리액트에 적용하는 방법은 아래를 통해 알아보자.

  1. 먼저 아래의 명령어를 통해 설치를 진행한다.
    react-editor만 설치할 경우 yarn에서 css파일을 찾지 못한다는 에러가 발생하기에
    반드시 @toast-ui/editor도 같이 설치해줘야 한다.
yarn add @toast-ui/editor @toast-ui/react-editor
  1. 이어서 .yarnrc.yml 파일에 아래의 코드를 추가하고 yarn명령어를 통해 설정을 업데이트 해준다.
    이 과정을 진행하지 않으면 prosemirror를 찾지 못했다는 에러가 발생한다.
    prosemirror는 toast editor를 개발한 환경으로 이 에러를 막기 위해 과정을 진행한다.
packageExtensions:
  '@toast-ui/editor@*':
    dependencies:
      prosemirror-transform: '*'
  1. 이제 공식 문서에 나온 예제처럼 간단히 사용하기만 하면된다.
import '@toast-ui/editor/dist/toastui-editor.css';
import { Editor } from '@toast-ui/react-editor';
import { useRef } from 'react';

cosnt Editor = () => {
  const editorRef = useRef();

    return (
      <>
        <Editor
          previewStyle="vertical"
          height="400px"
          initialEditType="markdown"
          initialValue="hello"
          ref={editorRef}
        />
      </>
    );
}

Editor 컴포넌트를 분할해 사용하기

위의 예시처럼 Editor를 사용할 수는 있지만, 일반적으로 페이지 컴포넌트에 에디터를 가져다
집어넣지는 않기에 에디터를 자식 컴포넌트로 두어 페이지에서 다루는 과정을 진행해보았다.
아래의 코드를 참고하자.

  • Editor Component
import { MutableRefObject } from 'react';
import '@toast-ui/editor/dist/toastui-editor.css';
import { Editor } from '@toast-ui/react-editor';

interface Props {
    editorRef: MutableRefObject<unknown>
}

const PostEditor: React.FC<Props> = ( props: Props ) => {

	return (
		<>
			<Editor
				height="100%"
				initialEditType="wysiwyg"
				useCommandShortcut={true}
				ref={(element) => {
					props.editorRef.current = element;
				}}
			/>
		</>
	);
};

export default PostEditor;
  • Page Component
import { useRef, useState } from 'react';
import PostEditor from '../../components/PostEditor/PostEditor';

const NewPostPage = (): JSX.Element => {
	const editorRef = useRef<any>(null);
	const [title, setTitle] = useState('');

	function PostSubmitHandler() {
		if(isValidContent()){
			const INSTANCE = editorRef.current?.getInstance();

			if(INSTANCE.mode==='wysiwyg'){
				const CONTENT = INSTANCE.getHTML();
				submitPost(title, CONTENT);
			}else if(INSTANCE.mode==='markdown'){
				const CONTENT = INSTANCE.getMarkdown();
				submitPost(title, CONTENT);
			}
		}
	}

	function isValidContent() {
		if(title===''){
			alert('제목을 입력해주세요.');
			return false;
		}else if(editorRef.current?.getInstance().getMarkdown()===''){
			alert('내용을 입력해주세요.');
			return false;
		}
		return true;
	}

	function submitPost(title: string, content: string) {
		console.log(title, content);
		//통신
	}

	return (
		<>
			<input type='text' placeholder='제목을 입력해주세요.' onChange={(e)=>{setTitle(e.target.value);}}/>
			<PostEditor editorRef={editorRef} />
			<button onClick={PostSubmitHandler}>등록</button>
		</>
	);
};

export default NewPostPage;

간단하게 에디터 컴포넌트와 페이지 컴포넌트를 나누어
제목, 내용을 받아 버튼으로 처리할 수 있도록 작성했다.

에디터에 설정값들을 미리 고정시켜두었지만, 에디터의 설정들은 변경이 가능하다.
따라서 작성한 에디터 컴포넌트에 props를 통해 Toast Editor 컴포넌트에 넘겨주는 방식으로
페이지 컴포넌트에서 설정할 수 있게 만드는게 더 나은 코드일 것이다.

Toast UI Viewer 적용하기

뷰어는 Editor보다 훨씬 더 쉽게 사용이 가능하다.
아래의 코드를 통해 확인할 수 있다.

  • Viewer Componenet
import { Viewer } from '@toast-ui/react-editor';
import '@toast-ui/editor/dist/toastui-editor-viewer.css';

interface Props {
    content: string
}

const PostViewer: React.FC<Props> = ( props: Props ) => {
	return(
		<>
			<Viewer initialValue={props.content} />
		</>
	);
};

export default PostViewer;

위처럼 간단히 사용할 수 있고 만약 뷰어 내부의 스타일을 적용하고 싶다면
div로 감싸져있는 형태로 존재하기에 아래처럼 적용해줄 수 있다.

Emotion.js를 사용한 예시지만 css를 주목해주길 바란다.

import { Viewer } from '@toast-ui/react-editor';
import { css } from '@emotion/react';
import '@toast-ui/editor/dist/toastui-editor-viewer.css';

interface Props {
    content: string
}

const PostViewer: React.FC<Props> = ( props: Props ) => {
	return(
		<div css={PostViewerStyle}>
			<Viewer initialValue={props.content} />
		</div>
	);
};

const PostViewerStyle = css`
    div{
        font-size: 16px;
		font-weight: 600;
    }
`;

export default PostViewer;

이렇게 간단히 Toast UI Editor를 React에 적용하는 방법을 알아봤다.
생각보다 간단하지만, 컴포넌트를 구성하는 방식은 다양하게 나올 수 있다.
어떤 코드가 더 좋은 코드인지를 생각해 개발해야 한다는 생각을 간단한 적용에서도 찾을 수 있어
조금 복잡한 심정을 갖게 했다.

다음에도 프로젝트 진행에 문제가 됐던 사항이 있다면 또 기록하며 생각해봐야겠다.

profile
개발 관련 지식을 기록하는 블로그입니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 2월 10일

Toast UI도 결국 ProseMirror 쓰더라구요

답글 달기