TypeScript 번외. input 태그 없이 이미지 업로드(React + typescript)

0

TYPESCRIPT

목록 보기
5/8
post-thumbnail

혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다

이미지 적용전, 적용후

프로젝트 컴포넌트 구현 전 기능 테스트 용으로 작성한 코드이다.
<input type="file"> 를 화면에 노출되지 않도록 CSS 적용하고, <img> 태그 클릭하면 활성화 되도록 했다.
미리보기 기능은 업로드된 파일으로 임시 url을 생성하여 표시한다.
url을 생성할 방법은 2가지가 있는데 그 중 URL 객체로 구현하는 방법이다.

import { useState, useRef } from "react";
import axios from "axios";
import styled from "styled-components";

const SImg = styled.img`
  width: 250px;
  height: 200px;
  object-fit: cover; // 비율 조정
  border: 1px solid black;
`;
const SImgInput = styled.input`
  display: none;
`;

const ImgUploader = () => {
  const [fileURL, setFileURL] = useState<string>("");
  const [file, setFile] = useState<FileList | null>();
  const imgUploadInput = useRef<HTMLInputElement | null>(null);

  const onImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    if (event.target.files) {
      setFile(event.target.files);

      const newFileURL = URL.createObjectURL(event.target.files[0]);
      setFileURL(newFileURL);
    }
  };
  const onImageRemove = (): void => {
    URL.revokeObjectURL(fileURL);
    setFileURL(""); // 렌더링 이미지 초기화
    setFile(null);
  };
  const submitHandler = async (event: React.MouseEvent<HTMLButtonElement>) => {
    event.preventDefault();

    /** 서버통신 */
    const formData = new FormData();

    if (file) {
      formData.append("file", file[0]);

      try {
        const response = await axios.post("/api/upload", formData, {
          headers: { "content-type": "multipart/form-data" },
        });
      } catch (error: any) {
        console.log("이미지업로드 에러 발생");
        throw new Error(error);
      }
    } else {
      alert("업로드할 이미지가 없습니다");
    }
  };
  return (
    <>
      <SImg
        src={
          fileURL
            ? fileURL
            : "https://cdn-icons-png.flaticon.com/512/1555/1555492.png"
        }
        alt=""
      ></SImg>
      <label htmlFor="img">이미지 업로드</label>
      <SImgInput
        type="file"
        id="img"
        accept="image/*"
        required
        ref={imgUploadInput}
        onChange={onImageChange}
      ></SImgInput>
      <button
        type="button"
        onClick={(event) => {
          event.preventDefault();
          if (imgUploadInput.current) {
            imgUploadInput.current.click();
          }
        }}
      >
        이미지 변경 버튼
      </button>
      <button type="button" onClick={onImageRemove}>
        제거 버튼
      </button>
      <button onClick={submitHandler}>submit</button>
    </>
  );
};

export default ImgUploader;

타입스크립트 기초만 겨우 듣고 작성한 코드라서 잘못된 부분이 있을 수 있다.
와이어프레임 작성 전 테스트용으로 구현한 것이라 실제 프로젝트에는 많은 변동이 될 예정이다.

0개의 댓글