server와의 이미지 파일 업로드가 아닌 프론트에서 받아온 이미지를 미리보기로 보여주는 과정을 기록한다.
파일받아오기는 기존에 진행했던 input file을 이용하였다.
const EscapeMoment = (): ReactElement => {
const onImgChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
if (e.target.files) {
const imgFile = e.target.files[0];
console.log(imgFile)
}
};
return (
<div>
<p>탈출의 순간 (선택)</p>
<div>
<div>
<input type="file" accept="image/*" onChange={onImgChange} />
<img src={camera} alt="사진선택" />
</div>
</div>
</div>
);
};
export default EscapeMoment;
위와같이 input을 클릭하면 이미지 업로드화면이 나오고 e.target.files[0]은 image의 정보가 나온다.
server에 업로드하게 된다면 imgFile을 multipart/form-data형식으로 만들어서 보내지만 바로 화면에 보여줄것이기 때문에 skip한다.
const EscapeMoment = (): ReactElement => {
const [newImg, setNewImg] = useState<[] | { id: number; img: string }[]>([]);
const onImgChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
if (e.target.files) {
const imgFile = e.target.files[0];
const img = window.URL.createObjectURL(imgFile);
setNewImg((prev) => {
if (!prev[0]) return [{ id: 1, img }];
const nextId = prev[prev.length - 1].id + 1;
return [...prev, { id: nextId, img }];
});
}
};
return (
<div>
<p>탈출의 순간 (선택)</p>
<div>
<div>
<input type="file" accept="image/*" onChange={onImgChange} />
<img src={camera} alt="사진선택" />
</div>
{newImg.map((item: { id: number; img: string }) => (
<div image={item.img}>
<img src={deleteImg} alt="사진삭제"/>
</div>
))}
</div>
</div>
);
};
export default EscapeMoment;
받아온 imgFile을 window.URL.createObjectURL()로 만들면 이미지의 주소만 string으로 저장된다.
이제 이미지 주소를 useState의 배열안에 저장해서 반복문으로 화면에 출력하면된다.
const EscapeMoment = (): ReactElement => {
const [newImg, setNewImg] = useState<[] | { id: number; img: string }[]>([]);
const onImgChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
if (e.target.files) {
const imgFile = e.target.files[0];
const img = window.URL.createObjectURL(imgFile);
setNewImg((prev) => {
if (!prev[0]) return [{ id: 1, img }];
const nextId = prev[prev.length - 1].id + 1;
return [...prev, { id: nextId, img }];
});
}
};
const onDelete = (clickedId: number) => {
setNewImg((prev) => {
return prev.filter((prevItem) => prevItem.id !== clickedId);
});
};
return (
<div>
<p>탈출의 순간 (선택)</p>
<div>
<div>
<input type="file" accept="image/*" onChange={onImgChange} />
<img src={camera} alt="사진선택" />
</div>
{newImg.map((item: { id: number; img: string }) => (
<div image={item.img}>
<img src={deleteImg} alt="사진삭제" onClick={() => onDelete(item.id)}/>
</div>
))}
</div>
</div>
);
};
export default EscapeMoment;
삭제 버튼을 눌렀을때 배열안에 같은 id값만 빼고 남겨서 삭제기능을 구현하였다.