Toast 에디터는 따로 설정해주지 않아도 에디터에 이미지를 첨부할 수 있다. 기본적으로 이미지 파일을 첨부하면 이미지가 base64로 인코딩 되어 삽입되는데, 그 길이가 매우 매우 상당하기 때문에 base64로 인코딩 된 이미지 그대로 DB에 넣어준다면 문제를 초래시킨다.
위처럼 이미지 하나를 첨부한 뒤, getHTML()
을 통해 contents를 살펴보면,
엄청난 양의 텍스트가 들어있는것을 볼 수 있다.
(너무 길어 콘솔에도 다 찍히지 않는다😳)
그러므로 우리는 이미지 첨부시 로직을 바꿔줄 필요가 있다.
addImageBlobHook을 사용하자
이미지 첨부 로직은 hooks
옵션의 addImageBlobHook
를 통해서 커스텀할 수 있다.
잠깐 구조를 살펴보면
export type HookMap = {
addImageBlobHook?: (blob: Blob | File, callback: HookCallback) => void;
};
addImageBlobHook
은 첫 번째 인자로 파일의 정보가 담긴 Blob객체나 File객체를, 두번째 인자로는 callback 함수를 받는다.
type HookCallback = (url: string, text?: string) => void;
callback함수에 이미지 정보를 담으면 에디터에 html(또는 마크다운) 형식으로 추가가 된다.
이제 File 객체를 받아와 s3에 저장한 뒤, s3 주소를 callback 함수에게 넘겨주도록 로직을 변경해보자.
해당 화면에서 확인 버튼을 누르면 addImageBlobHook
이 호출된다.
const onUploadImage = async (blob, callback) => {
console.log(blob);
};
return (
<div className="edit_wrap">
<Editor
previewStyle="vertical"
height="600px"
initialEditType="wysiwyg"
useCommandShortcut={false}
language="ko-KR"
ref={editorRef}
onChange={onChange}
plugins={[colorSyntax]}
hooks={{
addImageBlobHook: onUploadImage
}}
/>
</div>
);
위와 같이 코드를 추가해주고, 이미지 파일을 첨부했을 시 blob에 어떤 값이 담기는지 콘솔로 찍어보았다.
File 객체가 예쁘게 잘 담겨있는 것을 확인할 수 있다.
const onUploadImage = async (blob, callback) => {
const url = await uploadImage(blob);
callback(url, 'alt text');
return false;
};
uploadImage
를 통해 S3에 File 객체를 저장하고, S3 url 주소를 가져온다.
가져온 url을 callback
매서드로 넘겨주면 된다.
사진 첨부 후 onChange
에서 console.log(contents)
를 찍어보면 contents에 url이 잘 담겨있는 것을 확인할 수 있다!