제휴 맺기 게시글 작성, 수정, 삭제 기능 구현
제휴 맺기 게시글 작성
게시글을 작성할 때 들어가야 하는 내용은 다음과 같다.
먼저 이미지 업로드 기능을 처리해보자. 클라이언트에서 서버로 이미지 파일을 전송할 때, File 객체로 전송할 수 있다. 우리는 최대 3장의 이미지를 보낼 수 있도록 하기 위해 input 태그의 multiple 속성을 이용했다. 해당 속성을 true로 설정하면, 브라우저에서 파일을 업로드할 때 여러 개를 한 번에 업로드 할 수 있다.
해당 input 태그에서는 onChange 이벤트를 감지하여 onChangeImage라는 커스텀 함수를 실행하도록 되어있다.
const [imageUrl, setImageUrl] = useState([]);
const [postImages, setPostImages] = useState();
const onChangeImage = () => {
if (imageUrl.length >= 3) {
window.alert("3장 이상의 이미지는 등록할 수 없습니다.");
} else {
//업로드된 이미지가 3장 미만이라면 imageURL 배열에 추가
if (imgRef.current.files.length > 0) {
const imageFiles = [...imgRef.current.files];
console.log(imageFiles);
setPostImages(imageFiles);
imageFiles.map((item) => {
const reader = new FileReader();
reader.readAsDataURL(item);
reader.onloadend = () => {
setImageUrl((prev) => [...prev, reader.result]);
};
});
}
}
};
imageUrl이라는 배열은 미리보기를 위한 배열이고, postImages는 서버로 보내기 위한 이미지 배열이다. 두 변수를 따로 분리한 이유는 미리보기할 때 필요한 이미지의 타입과 서버로 보내기 위한 이미지의 타입이 다르기 때문이다.
onChangeImage 에서는 사용자가 업로드한 파일을 가져와서 PostImages에 그대로 담아주고, 미리보기를 위한 imageUrl에는 FileReader()를 통해 변환을 한 후에 담아준다.
<div className="photoContainer">
{imageUrl.map((item, index) => {
return (
<div key={index}>
<img alt={index} className="uploadedPhoto" src={item}></img>
<button id={index} className="deletePhotoBtn" type="button">
<IoMdCloseCircle
id={index}
size={"1.5em"}
color={"B8B8B8"}
onClick={deletePhoto}
></IoMdCloseCircle>
</button>
</div>
);
})}
</div>
imageUrl 배열을 map 함수를 통해 하나씩 렌더링 해준다.
이렇게 잘 표시된 미리보기에는 x 버튼이 달려있는데, 이 버튼을 누르면 해당 이미지의 업로드를 취소할 수 있어야 한다.
const deletePhoto = (e) => {
//버튼 바깥쪽이나 빈 공간을 잘못 클릭한 경우 처리
if (!e.target.parentNode.parentNode.id) {
return;
} else {
newImageURL = imageUrl.filter((item, index) => {
return index !== Number(e.target.parentNode.parentNode.id);
});
setImageUrl(newImageURL);
}
};