[NEXT] TOAST Editor에서 이미지 업로드하기(hooks)

Toast Editor에서 이미지 업로드 하기

Toast Editor는 이미지 업로드를 위한 UI를 아래와 같이 제공하고 있다.

스크린샷 2023-08-26 오전 11 35 09

그리고 이미지를 선택하고 OK 버튼을 누르면 이미지가 아래와 같이 노출되게 된다.

스크린샷 2023-08-26 오전 11 34 58

좌측에 노출된 복잡한 코드는 base64로 인코딩된 이미지 코드인데,유저가 이렇게 실사용하기는 어려울 것 같다.

그래서 아래와 같이 수정을 해보려고 한다.

  1. 업로드할 이미지를 선택한다.
  2. OK버튼을 누르면 선택한 이미지를 서버에 업로드한다.
  3. 업로드가 완료되면, 업로드된 이미지의 주소를 받는다.
  4. 업로드 된 이미지의 주소를 에디터에 노출한다.

1번은 이미 구현되어 있다. 2번부터 직접 구현해보도록 하자.

OK버튼을 누르면 이미지 업로드 함수를 실행하기

그런데 OK 버튼을 눌렀을 때 내가 작성한 이미지 업로드 함수가 바로 실행되도록 어떻게 해야할까?

이전에 EditorOptions의 문서에서 hooks라는 Props를 본적이 있었다.

🔗 EditorOptions 문서 바로가기 🔗

스크린샷 2023-08-26 오전 11 53 49

설명에 이미지 업로드를 위한 hooks라고 당당히 기재되어 있는 것을 볼 수 있다. 역시 문서는 잘 써놓은 것 같다.

hooks를 사용하면 되지 않을까 예상은 되는데 사용하는 방법은 어떻게 될까?

조금 더 알아봐야겠다.

// node_modules/@toast-ui/editor/types/editor.d.ts
export interface EditorOptions {
 (...)
  hooks?: HookMap;
  (...)
}

export type HookMap = {
  addImageBlobHook?: (blob: Blob | File, callback: HookCallback) => void;
};

type HookCallback = (url: string, text?: string) => void;

hooks에 대한 타입을 확인해보니, addImageBlobHook이라는 함수가 있고, 이 함수는 blobcallback을 인자로 받는다.

그리고 callbackurltext를 인자로 받는다.

이제 blobcallback을 인자로 받는 이미지 업로드 함수를 만들어서 연결 해주면 될 것 같다.

이미지 업로드 함수

export const imageAPI = {
  postUploadImage: async (image: File | Blob, callback: HookCallback) => {
    // 이미지 업로드를 위한 formData 생성
    const formData = new FormData();
    formData.append('file', image);

    try {
      // 이미지 업로드 후 이미지 id 받기
      const result = await axios({
        method: 'post',
        url: BLOGRASS_IMAGE_UPLOAD,
        data: formData,
      });

      // 이미지 id를 이용하여 이미지 url 생성
      const imageUrl =
        await `${BLOGRASS_IMAGE_BUCKET_URL}/${result.data.result[0]}`;

      // callback에 이미지 url과 alt_text를 인자로 넣어준다.
      callback(imageUrl, 'alt_text');
    } catch (error) {
      console.error(error);
    }
  },
};
  1. imagecallback을 인자로 받는다.
  2. image를 서버에 업로드 한다.
  3. 업로드가 완료되면, 업로드된 이미지의 URL을 받는다.
  4. callback에 이미지의 URL과 텍스트를 인자로 넣어준다.

hooks에 이미지 업로드 함수 연결하기

아래와 같이 hooks에 이미지 업로드 함수를 연결해주면 된다.

export default function PostEditor({
  editorRef,
}: {
  editorRef: RefObject<Editor>;
}) {
  return (
    <Editor
      ref={editorRef}
      previewStyle='vertical'
      height='800px'
      initialEditType='markdown'
      placeholder='Write Something'
      hideModeSwitch={true}
      language='ko-KR'
      hooks=
    />
  );
}

스크린샷 2023-08-26 오후 6 38 19

코드 블럭에 hooks를 추가해주었다.(왜 안보이지..?)

테스트를 해보니 아래와 같이 이미지가 업로드 되는 것을 확인 할 수 있었다.

스크린샷 2023-08-26 오후 12 13 27