[텍스트 에디터 비교] react-draft-wysiwyg

rosyoon·2022년 11월 23일
12

텍스트 에디터를 사용할 일이 생겨서 라이브러리들을 비교해 봤다.

서치하면서 가장 많이 보였던 라이브러리는 draft와 quill였고 jodit도 사용하기 괜찮을 것 같아서 후보에 넣었다.

npm trends에 다운로드 수를 비교해보면 quill이 압도적이진 않지만 높게 나와있다..

주간 다운로드 수 : draft > quill > jobit
크기 : quill < draft < jodit

- draft (react-draft-wysiwyg)

  • 리액트를 기준으로 개발됨(이미지 업로드 기능 추가됨)
  • 값이 객체로 반환되는데 이를 view에 표시하기 위해선 추가로 라이브러리를 설치해야한다.
  • 사용도가 높은 만큼 구글링 검색이 쉽다.

- quill.js

  • 순수 js로 동작
  • 파일 업로드는 따로 플러그인을 만들어야 함
  • 값이 string으로 반환됨

- jodit

  • 순수 ts로 동작
  • 파일 업로드는 따로 플러그인 만들어야 함
  • 값이 string으로 반환됨
  • 짧은 코드로 구현 가능
  • 입력 버그 있음
  • 구글링을 해도 정보가 거의 없음

이미지는 서버가 없어서 임시로 함수만 연결해놨지만
사용해본 결과 react-draft-wysiwyg이 제일 완성도가 높은 라이브러리라고 느껴졌다.

그래서 react-draft-wysiwyg로 간단하게 구현해봤다.

import React, { useState } from "react";
import styled from "styled-components";
import { Editor } from "react-draft-wysiwyg";
import { EditorState, convertToRaw } from "draft-js";
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
import draftjsToHtml from "draftjs-to-html";

const Container = styled.div`
  width: 100%;
`;

const RowBox = styled.div`
  width: 100%;
  display: flex;
`;

const Viewer = styled.div`
  width: calc(50% - 40px);
  height: 400px;
  padding: 20px;
  margin-top: 20px;
  border: 2px solid gray;
`;

const Draft = () => {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());
  const [htmlString, setHtmlString] = useState("");

  const updateTextDescription = async (state) => {
    await setEditorState(state);
    const html = draftjsToHtml(convertToRaw(editorState.getCurrentContent()));
    setHtmlString(html);
  };

  const uploadCallback = () => {
    console.log("이미지 업로드");
  };

  return (
    <>
      <div>draft</div>
      <Container>
        <Editor
          placeholder="게시글을 작성해주세요"
          editorState={editorState}
          onEditorStateChange={updateTextDescription}
          toolbar={{
            image: { uploadCallback: uploadCallback },
          }}
          localization={{ locale: "ko" }}
          editorStyle={{
            height: "400px",
            width: "100%",
            border: "3px solid lightgray",
            padding: "20px",
          }}
        />
      </Container>
      <RowBox>
        <Viewer dangerouslySetInnerHTML={{ __html: htmlString }} />
        <Viewer>{htmlString}</Viewer>
      </RowBox>
    </>
  );
};

export default Draft;

실행 결과 ⬇️

1개의 댓글

comment-user-thumbnail
2023년 11월 27일

잘 보고 갑니다!

답글 달기