여행가는개발자

에디터 사용기 (tinymce-react) 본문

React

에디터 사용기 (tinymce-react)

kimsoonil 2023. 11. 7. 15:56
728x90
반응형

어드민 프로젝트를 제작하면서 에디터를 사용하게 되었는 데 그부분을 한번 정리해보려고한다.

 

프로젝트에 에디터를 도입하게 되면서 여러 에디터 라이브러리를 사용해봤다.

그 중 tinymce-react(https://www.tiny.cloud/docs/integrations/react/) 라이브러리를 도입하게되었다.

여러 에디터 라이브러리를 봤지만 이 라이브러리를 고르게 된 이유는

  1. 사용이 무료
  2. docs 가 잘 정리 되어있음
  3. 기본 에디터에 충실하고 기능이 명확히 있음

이러한 점으로 개발하게 됬다.

 

간단한 사용법은 

$ npm install --save @tinymce/tinymce-react

 

 import React, { useRef } from 'react';
 import { Editor } from '@tinymce/tinymce-react';

 export default function App() {
   const editorRef = useRef(null);
   const log = () => {
     if (editorRef.current) {
       console.log(editorRef.current.getContent());
     }
   };
   return (
     <>
       <Editor
         onInit={(evt, editor) => editorRef.current = editor}
         initialValue="<p>This is the initial content of the editor.</p>"
         init={{
           height: 500,
           menubar: false,
           plugins: [
             'advlist autolink lists link image charmap print preview anchor',
             'searchreplace visualblocks code fullscreen',
             'insertdatetime media table paste code help wordcount'
           ],
           toolbar: 'undo redo | formatselect | ' +
           'bold italic backcolor | alignleft aligncenter ' +
           'alignright alignjustify | bullist numlist outdent indent | ' +
           'removeformat | help',
           content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }'
         }}
       />
       <button onClick={log}>Log editor content</button>
     </>
   );
 }

 

으로 사용하면 되고 나같은 경우는 

 

import React, { FC, useRef } from 'react';

import { Editor } from '@tinymce/tinymce-react';
import axiosClient from 'src/hooks/axiosInstance';

const TinyMceEditor: FC<any> = ({ editorRef }) => {
  // const editorRef = useRef<any>();

  const tinymcePlugins = [
    'advlist',
    'autolink',
    'link',
    'image',
    'lists',
    'charmap',
    'preview',
    'anchor',
    'pagebreak',
    'searchreplace',
    'wordcount',
    'visualblocks',
    'code',
    'fullscreen',
    'insertdatetime',
    'media',
    'table',
    'emoticons',
    'template',
  ];
  const tinymceToolbar =
    'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | ' +
    'bullist numlist outdent indent | link image | table preview media fullscreen | ' +
    'forecolor backcolor emoticons ';

  return (
    <Editor
      onInit={(e, editor) => (editorRef.current = editor)}
      init={{
        plugins: tinymcePlugins,
        toolbar: tinymceToolbar,
        min_height: 500,
        menubar: false,
        branding: false,
        statusbar: false,
        automatic_uploads: true,
        block_formats: '제목1=h2;제목2=h3;제목3=h4;본문=p;',
        file_picker_types: 'image',
        images_upload_handler: blobInfo =>
          new Promise((resolve, reject) => {
            const formData = new FormData();
            formData.append('file', blobInfo.blob());
            axiosClient
              .post(
                `${process.env.NEXT_PUBLIC_API_ENDPOINT}/notice/web/upload`,
                formData,
              )
              .then(res => {
                resolve(res.data.result.imageUrl);
              })
              .catch(e => {
                reject(e);
                console.log('e', e);
              });
          }),
      }}
    />
  );
};

export default TinyMceEditor;

 

다음과 같이 적용하였다.

 

Docs에 나온 코드와 다른점은 init 안에 images_upload_handler 코드인데

 

에디터를 사용해보면 에디터를 작성하고 나서 value를 가져오면 HTML 코드를 제공해주는 것을 확인할 수 있다.

 

그런데 이미지를 삽입하게 되면 해당 이미지가 base64로 변환되어 <img> 태그에 src에 박혀 있는 것을 확인할수 있다,

이 과정을 파악했을때 라이브러리 자체에서 이미지를 변환하여 사용하는 것을 파악했다.

그래서 이미지를 한개 이상 추가하게 되면 HTML코드가 상당히 길어져 서버에 부하가 오게 된다. 

대안한 방법이 이미지를 삽입하자마자 서버에 요청하여 이미지만 폼데이터로 보내고 해당 이미지를 URL파일로 팓아서 쓰는 방법이였다.

위 코드가 다음과 같은 기능이라고 볼수 있다. 

 

코드펜으로 테스트 해보시고 사용할 수 있습니다.

https://codepen.io/pen

728x90
반응형

'React' 카테고리의 다른 글

Spread 연산자와 Rest 연산자  (0) 2023.11.14
Recoil을 활용하여 팝업 공통화하기  (0) 2023.10.12
Recoil  (1) 2023.10.10
Json-server  (0) 2023.09.15
Typescript vs Javascript  (0) 2023.09.15