개발일기/Web

[React] 파일 업로드 및 미리보기 구현 + input태그 버튼연결하기

DongKeun2 2022. 10. 11. 13:36
이번 프로젝트에서 이미지 파일을 업로드하여 그것과 비슷한 그림체의 웹툰을 추천해주는 부가기능이 있었습니다.
이 페이지의 기능 구현을 담당하여 필요한 기술들을 학습하면서 배운 내용을 기록해두려합니다.

다음과 같은 화면에서 그림을 업로드 할 수 있게 버튼을 만들어주었는데,

파일을 업로드하는 버튼이 너무 밋밋하여 이를 커스텀하고자 input과 버튼을 연결해서 css를 입혔습니다.

// upload.jsx

...


	// 버튼의 for와 input의 id를 일치시켜 연결시켜준다.
    <InputBtn htmlFor="input_img">{fileImage
    	? "다시 업로드 하기"
    	: "그림 업로드 하기"}
    </InputBtn>
    
  <input
    id="input_img"
    name="imggeUpload"
    type="file"
    accept="image/*"
    onChange={saveFileImage}
    style={{ display: "none" }}
  />
  
 ... 
  
const InputBtn = styled.label`
  box-shadow: 2px 3px 2px rgba(0, 0, 0, 0.5);
  border: 0.3vw solid white;
  border-radius: 0.6vw;
  background-color: #d1e2ff;
  padding: 10px 10px;
  margin-top: 20px;
  font-weight: 700;
  font-size: 1vw;
  cursor: url(${hover}) 13 13, auto;
  &:hover {
    background-color: #99c0ff;
    border: 0.3vw solid #99c0ff;
  }
`;

일단 input에서 이미지 파일을 받아올 수 있도록 type에 file, accept에 image/*을 넣어주었습니다.
그리고 커스텀을 위해 input의 display를 none으로 만들어주고 (hidden도 가능)

input 태그의 id와 버튼의 for을 일치시켜 연결하였습니다.
버튼 css는 styled-components를 활용하였으며 이미지 파일이 있다면 다시 업로드 할 수 있도록 구현했습니다.

 

const [fileImage, setFileImage] = useState("");

const saveFileImage = (event) => {
  setFileImage(URL.createObjectURL(event.target.files[0]));
};

이미지 파일의 미리보기를 위해서 URL.createObjectURL을 활용해

이미지 파일 객체의 데이터의 참조를 가리키는 새로운 객체 URL을 생성하여 state에 파일을 저장하였습니다.

<ImgBox>
  <ResultImg
    id="canvas"
    alt="sample"
    src={fileImage}
    style={{ margin: "auto" }}
  />
</ImgBox>


const ImgBox = styled.div`
  width: 20vw;
  min-width: 300px;
  height: 20vw;
  min-height: 300px;
  border: 3px solid;
  background-color: white;
  border-radius: 10%;
  overflow: hidden;
`;

const ResultImg = styled.img`
  width: 100%;
  height: 100%;
  object-fit: fill;
  margin-left: 0.4vw;
`;

미리보기를 위해서는 img 태그의 src에 이미지를 넣어주기만 하면 됩니다.

 

제 증명사진을 업로드하여 결과를 보겠습니다.

 

사진을 업로드하게 되면 제출버튼이 활성화되며 다른 사진을 업로드하고 싶다면 다시 업로드 할 수도 있습니다.

 

제출한다면 잠시동안 로딩 시간을 가진 후 자체적으로 분류한 그림체 분석을 통해 비슷한 웹툰을 추천해줍니다.