<aside> 💡 프로젝트에 필요해서 사용하게 된 React-summernote summernote에서 제공하는 기본 이미지 업로드 기능은 기본 base64로 인코딩 저장하는 방식으로 데이터 관리를 위해 이미지 업로드 이벤트 메서드인 onImageUpload를 커스텀하여 원하는 경로(S3)에 저장 후 에디터에 반영되는 과정을 기록해본다.
</aside>
yarn add react-summernote
yarn add jquery // jquery가 없을 경우
yarn add bootstrap@4 // bootstrap이 없을 경우
const webpack = require("webpack");
module.exports = {
// ..
plugins: [
// 에디터를 위해 제이쿼리 추가
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
}),
],
};
import React, { useEffect } from "react";
import { useSelector } from "react-redux";
// imports for summernote
import ReactSummernote from "react-summernote";
import "react-summernote/dist/react-summernote.css";
import "react-summernote/lang/summernote-ko-KR";
import "bootstrap/js/dist/modal";
import "bootstrap/js/dist/dropdown";
import "bootstrap/js/dist/tooltip";
import "bootstrap/dist/css/bootstrap.css";
const SummernoteEditor = ({ defaultValue = "", onUploadImg }) => {
// 3. onUploadImg 이벤트의 결과 subscribe
const { common } = useSelector((state) => ({
common: state.common.postImgUpload,
}));
// 4. onUploadImg 이벤트의 변경을 useEffect로 감지
useEffect(() => {
if (!common.data) return;
// 5. post api 후 리턴된 URL(common.data)을 insertImage 메서드로 에디터에 반영
ReactSummernote.insertImage(common.data);
}, [common.data]);
const onChange = (content) => {
// 6. 변경 데이터 감지 !
console.log("onChange ", content); // <p><img src="<https://storage.vicky.com/admin/20201029085457965.png>" style="width: 100px;"><br></p>
};
// 1. 이미지 업로드 커스텀
const onImageUpload = (images) => {
for (let i = 0; i < images.length; i++) {
const file = images[i];
if (file === undefined || file === null) {
alert("파일을 먼저 골라주세요.");
return;
}
const formData = new FormData();
formData.append("data", file);
onUploadImg(formData); // 2. onUploadImg라는 커스텀 이벤트 실행
}
};
return (
<div>
<ReactSummernote
children="내용을 입력해주세요."
options={{
lang: "ko-KR",
height: 380,
dialogsInBody: true,
toolbar: [
["style", ["style"]],
["font", ["bold", "underline", "clear"]],
["fontname", ["fontname"]],
["para", ["ul", "ol", "paragraph"]],
["table", ["table"]],
["insert", ["link", "picture", "video"]],
["view", ["fullscreen", "codeview"]],
],
}}
onChange={onChange}
onImageUpload={onImageUpload}
/>
</div>
);
};
export default SummernoteEditor;
<SummernoteEditor
defaultValue={inputs.answer}
onUploadImg={onUploadImg}
/>