image 파일 받아서 미리보기

이경준·2021년 6월 14일
1


server와의 이미지 파일 업로드가 아닌 프론트에서 받아온 이미지를 미리보기로 보여주는 과정을 기록한다.

1.파일 받아오기

파일받아오기는 기존에 진행했던 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한다.

2. 파일 화면에 출력하기

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의 배열안에 저장해서 반복문으로 화면에 출력하면된다.

3.삭제하기

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값만 빼고 남겨서 삭제기능을 구현하였다.

profile
내가 기억하기위한 블로그

0개의 댓글