react-quill을 사용해서 글 내에 이미지를 삽입하면
자동으로 base64변환해서 사이즈가 커진다.
이미지 핸들러를 이용하여 이미지를 서버나 클라우드에 저장하고 url을 사용하여
<img src="" />
String으로 저장되는 contents의 크기를 줄이기로했다.
import React, { useEffect, useMemo, useRef, useState } from "react"
import ReactQuill , {Quill} from "react-quill"
import '../../assets/css/quill.snow.css'
quill 을 사용할떄 필요한 기본 들만 임포트 해줘도 충분하다.
const quillRef = useRef(null);
useEffect(() => {
const quill = quillRef.current;
// console.log(quill);
const handleImage = () => {
// 이미지 핸들 로직
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
const file = input.files[0];
// 현재 커서 위치 저장
// const range = getEditor().getSelection(true);
const range = quill.selection
// 서버에 올려질때까지 표시할 로딩 placeholder 삽입
quill.getEditor().insertEmbed(range.index, "image", `/images/loading.gif`);
try {
// S3에 업로드 한뒤 이미지 태그에 삽입할 url을 반환받도록 구현
const formData = new FormData();
formData.append('file' , file)
const result = await actionUploadEditorImage(formData);
const url = result.data
console.log(url);
// 정상적으로 업로드 됐다면 로딩 placeholder 삭제
quill.getEditor().deleteText(range.index, 1);
// 받아온 url을 이미지 태그에 삽입
quill.getEditor().insertEmbed(range.index, "image", url);
// 사용자 편의를 위해 커서 이미지 오른쪽으로 이동
quill.getEditor().setSelection(range.index + 1);
} catch (e) {
quill.getEditor().deleteText(range.index, 1);
}
};
}
if (quillRef.current) {
// const { getEditor } = quillRef.current;
const toolbar = quill.getEditor().getModule("toolbar");
toolbar.addHandler("image", handleImage);
}
}, []);
아래 블로그를 참고하여 작업하였다.
동작은 이러하다.
1. [프론트] 이미지 삽입
2. [프론트] 로딩gif 삽입
3. [서버] 이미지 url 추출 (나의 경우 S3에 업로드후 url 생성했다)
4. [프론트] 로딩gif삭제
5. [프론트] 서버에서 받은 url 로 이미지 태그에 삽입
base64 로 5천만줄 되던 String값이 img태그 하나로 줄어드는 매직이된다.
const toolbarOptions = [
// [{ 'font': [] }], //웹사이즈 기본폰트를 사용하기위해 제거
[{ header: "1" }, { header: "2" }, { 'header': [1, 2, 3, 4, false] }],
['bold', 'italic', 'underline','strike'],
[{ 'color': [] }, { 'background': [] }],
[{'list': 'ordered'}, {'list': 'bullet'}, {'list': 'check'}],
[{'indent': '-1'}, {'indent': '+1'}],
[{ 'align': [] } , { direction: "rtl" }],
['link' , 'image'],
["code-block"],
[{ script: "sub" }, { script: "super" }],
[{ table: true }]
]
const formats = [
// 'font',
'header',
'bold', 'italic', 'underline', 'strike',
'color', 'background',
'list', 'bullet', ,'check',
'indent',
'align', 'direction',
'link', 'image',
"code-block",
"script",
"table",
]
const modules = useMemo(()=>{
return {
// table: true,
// tableUI: true,
toolbar: {
container: toolbarOptions,
},
// ImageResize: { modules: ['Resize'] },
imageDrop: true,
clipboard: {
matchVisual: false // toggle to add extra line breaks when pasting HTML:
},
}
})
모듈에 ImageResize: { modules: ['Resize'] },
설정해주지 않아도 핸들링 가능하다.
되려 나는 모듈에 설정해서 오류가났다 delta가 없다나?
<ReactQuill
id={id}
ref={quillRef}
className="form-control text-editor"
theme = 'snow'
modules = {modules}
formats = {formats}
value = {value || ''}
onChange = {(content, delta, source, editor) => setVlaue(editor.getHTML())}
style = {{width: '100%'}}
readOnly={isDisable}
/>
HTML 코드는 위와 같다.
728x90
반응형
'Front-end > React' 카테고리의 다른 글
[대시보드] amcharts 라이브러리 사용 리액트 Bar 차트 (0) | 2023.08.27 |
---|---|
ReactQuill 리액트 글쓰기 에디터 이미지 드롭하여 삽입하기 (2) | 2023.08.14 |
리액트 글쓰기 라이브러리 사용 해서 에디터 만들기 react-quill 에디터 이미지 파일 리사이즈 (0) | 2023.08.10 |
[React] 새창 Pop up 데이터 넘겨주는 방법 (0) | 2023.07.19 |
[React] 새창 Pop up 열기 (0) | 2023.06.13 |
댓글