시작하기에 이어서 에디터에 마크다운으로 작성한 내용(이미지 포함)을 서버에 보내는 과정을 회고해 봅니다.
Editor는 markdown, wysiwyg 두가지 방식을 제공하는데, 프로젝트에서는 markdown을 디폴트로 설정했었다.
아무튼, 에디터에 작성된 내용은 getHTML
과 getMarkdown
로 가져올 수 있다. 최소 글자수 등 유효성 검사 후 submit을 하면 getHTML
로 가져온 내용을 직렬화하고 서버에 전송한다.
const editorRef = useRef();
const onChangeHandle = () => {
const htmlElement = editorRef.current.getInstance().getHTML();
const json = JSON.stringify(htmlElement);
console.log(json);
return onChange(json);
};
서버에서 가져와 JSON.parse()
로 content
에 전달했다.
<Viewer initialValue={JSON.parse(item.content)} />
에디터를 작성할 때 이미지를 업로드하면 다음과 같은 base64로 인코딩된 문자열 데이터가 입력된다. 아래 이미지처럼 스크롤이 짧아질 정도로 이미지 하나의 데이터가 어마어마하다.
서버에 base64 데이터를 그대로 전송할 수 없고 S3 등 서버에 업로드를 하고 이미지 경로를 가져와 넣어주어야 했다.
이미지 업로드는 hooks
프롭으로 오브젝트에 addImageBlobHook 속성을 전달에서 제어할 수 있다. 에디터 영역에 이미지를 드래그 & 드롭하거나 이미지 업로드 버튼을 눌렀을 때, 이벤트를 제어할 수 있다.
<Writer
previewStyle="tab"
height={height}
initialEditType="markdown"
initialValue="## *Your* **markdown** here"
ref={editorRef}
plugins={[[codeSyntaxHighlight, { highlighter: Prism }]]}
hideModeSwitch={true}
onChange={onChangeHandle}
useCommandShortcut={false}
hooks={{
addImageBlobHook: onUploadImage,
}}
toolbarItems={[
['heading', 'bold', 'strike'],
['hr', 'quote'],
['ul', 'ol', 'task'],
['table', 'image', 'link'],
['code', 'codeblock'],
]}
/>
onUploadImage
함수는 blob
과 callback
인자를 받을 수 있다. blob은 콘솔에 찍어보면 file 객체이며, formData
에 담아 s3 서버에 전달한다. callback(url, string)
은 파일 경로와 대체텍스트를 인자로 받고 있는데, 응답으로 받은 서버에 저장된 경로와 객체의 파일명을 대체 텍스트로 전달한다.
const onUploadImage = async (blob, callback) => {
console.log(blob)
await fetchUploadImage(blob).then((path) => {
console.log(path);
callback(path, blob.name);
});
return false;
};