새롭게 추가할 사진 배열 설정하기
const [ photoToAddList, setPhotoToAddList ] = useState([]);
{ id: {사진 이름},
file: {사진 파일},
url: {사진 파일에 해당되는 URL}
}
input 태그에 사진 핸들러 설정하기
<input
type="file"
accept="image/jpg, image/jpeg, image/png"
multiple
ref={photoInput}
onChange={(e) => handlePhoto(e)}
style={{display: 'none'}}
/>
handlePhoto
를 설정했다.사진 핸들러에서 배열 저장하기
const handlePhoto = (e) => {
const temp = []
const photoToAdd = e.target.files;
for (let i = 0; i < photoToAdd.length; i++) {
temp.push({ id: photoToAdd[i].name, file: photoToAdd[i], url: URL.createObjectURL(photoToAdd[i]) })
};
setPhotoToAddList(temp.concat(photoToAddList))
};
URL.createObjectURL
를 이용했다.temp
)을 설정하여, 한 번 등록할 때 등록된 여러 장의 사진들을 임시 배열에 담은 후, for문을 다 돌고 난 다음 해당 임시 배열을 원 배열에 concat 하는 방식을 택했다.photoToAddList.concat(temp)
대신 temp.concat(photoToAddList)
로 작성했다. const photoToAddPreview = () => {
return photoToAddList.map((photo) => {
return (
<div className="photoBox" key={photo.url}>
<CloseCircleFilled className="photoBoxDelete"}/>
<img className="photoPreview" src={photo.url} />
</div>
)
})
};
map
을 이용해 photoToList
의 각 요소들을 하나씩 꺼내 div에 담는다.photoToAddPreview
를 함수형으로 설정하지 않고 바로 map으로 연결하는 경우 (const photoToAddPreview = photoToAddList.map(...)
) 에는 따로 리턴값을 설정하지 않더라도 컴포넌트가 생성되는 것 같다. { photoToAddPreview() }
const onRemoveToAdd = (deleteUrl) => {
setPhotoToAddList(photoToAddList.filter(photo => photo.url != deleteUrl))
}
<CloseCircleFilled
className="photoBoxDelete"
onClick={()=>onRemoveToAdd(photo.url)}
/>
function PhotoUploader() {
// 사진 업로드 버튼 이벤트 핸들러
const photoInput = useRef();
const handleClick = () => {
photoInput.current.click();
};
// 사진 등록하기 및 미리보기 기능 구현
const [ photoToAddList, setPhotoToAddList ] = useState([]);
const photoToAddPreview = () => {
return photoToAddList.map((photo) => {
return (
<div className="photoBox" key={photo.url}>
<CloseCircleFilled className="photoBoxDelete" onClick={()=>onRemoveToAdd(photo.url)}/>
<img className="photoPreview" src={photo.url} />
</div>
)
})
};
const onRemoveToAdd = (deleteUrl) => {
setPhotoToAddList(photoToAddList.filter(photo => photo.url != deleteUrl))
}
const handlePhoto = (e) => {
const temp = []
const photoToAdd = e.target.files;
for (let i = 0; i < photoToAdd.length; i++) {
temp.push({ id: photoToAdd[i].name, file: photoToAdd[i], url: URL.createObjectURL(photoToAdd[i]) })
};
setPhotoToAddList(temp.concat(photoToAddList))
};
return (
<div className="contentWrapper">
<div className="contentBody photoUploaderWrapper">
<Row justify="end">
<p>클로이와 홍대 나들이</p>
</Row>
<div className="photoUploaderContent">
<div className="photoBox addPhoto">
{/* <PlusOutlined /> */}
<PictureFilled onClick={handleClick} />
<input
type="file"
accept="image/jpg, image/jpeg, image/png"
multiple
ref={photoInput}
onChange={(e) => handlePhoto(e)}
style={{display: 'none'}}
/>
</div>
{ photoToAddPreview() }
{ photoAddedPreview() }
</div>
</div>
<Row justify="center">
<Button className="photoUploadComplete" onClick={ savePhoto }>기록하기</Button>
</Row>
</div>
);
}
export default PhotoUploader;
이렇게! 삭제 버튼이 있는 사진 미리보기 완성!