보통 이미지 업로드를 위해 해당 파일을 선택하면, 선택한 파일을 미리 보여주고는 한다. 이전에도 구글링을 해서 힌트를 얻었고 이후 더 간편한 구현 방식을 찾게 되어 기억해 놓았었는데, 최근에 똑같은 문제를 직면했을 때 그 방식이 떠오르지 않아서 이번에는 제대로 정리하고 넘어가고자 한다.
현재는 파일을 선택했을 때, 파일의 제목만 표시된다. 하지만 내가 원하는 것은 파일을 선택했을 때, 해당하는 이미지 파일의 url을 가져온 후 이를 img 태그의 src로 설정해주어 미리보기화 시키는 것이다.
만약 이를 위해 단순하게 input의 change 이벤트 핸들러로 value값을 통해 url에 접근하고자 하면, 해당하는 경로는 크롬의 보안 상 이슈로 fakePath 처리된다. 이용자가 임의로 이러한 방식을 통해, 파일을 탈취할 가능성도 있기 때문이다.
그렇기에 우리는 우회적인 방법이 필요한데, 첫 번째로는 fileReader를 이용한 방식이다.
첫 번째 방법 : FileReader 사용
import React, { useState } from "react";
export default function AdminBackground() {
const [imageUrl, setImageUrl] = useState();
return (
<>
{/* 이미지 파일의 url 있을 시 src로 넘겨 줌. */}
{imageUrl && (
<img
src={imageUrl}
alt="miribogi"
className="w-96 absolute top-16 right-20"
></img>
)}
<form className="absolute right-0">
<input
type="file"
onChange={(e) => {
// 파일의 정보를 읽어들이기 위한 FileReader 생성.
const reader = new FileReader();
// FileReader을 통해 새로운 파일을 읽어왔을 때, 인자로 주어진 콜백함수를 실행하도록 설정.
reader.onload = (fileInfo) => {
// 로드된 파일의 정보를 인자로 받으면, 해당 인자의 .target.result를 통해 파일 url에 접근 가능.
// 접근한 url을 state로 설정해 줌.
setImageUrl(fileInfo.target.result);
};
// reader에 onload 설정이 끝났으니, 이제 reader를 통해 파일을 읽어 옴.
reader.readAsDataURL(e.target.files[0]);
}}
/>
</form>
</>
);
}
뭐야 들여쓰기 왜이래
아무튼, 아주 깔끔하게 처리되었다.
두 번째 방법 : URL.createObjectUrl API 사용
이 방식은 API의 메소드 그대로, 주어진 오브젝트를 토대로 새로운 url을 생성하는 방식이다. 인자로 해당 파일을 넘겨 주면 url을 리턴해 주므로, 이 url을 그대로 전달해주기만 하면 된다.
import React, { useState } from "react";
export default function AdminBackground() {
const [imageUrl, setImageUrl] = useState();
return (
<>
{/* 이미지 파일의 url 있을 시 src로 넘겨 줌. */}
{imageUrl && (
<img
src={imageUrl}
alt="miribogi"
className="w-96 absolute top-16 right-20"
></img>
)}
<form className="absolute right-0">
<input
type="file"
onChange={(e) => {
const file = e.target.files[0];
const url = URL.createObjectURL(file);
setImageUrl(url);
}}
/>
</form>
</>
);
}
이것도 역시 동일한 결과를 가져온다.
두 가지 방식은 조금씩의 차이가 존재하겠지만, 크게 다르지는 않으므로 입맛대로 적용하여 사용하면 될 것 같다. 그러나 나에게는 조금 더 코드가 간결한 후자의 방식이 조금 더 와닿는다.
'WEB > FE(HTML,CSS,JS | React)' 카테고리의 다른 글
[React] 무한루프 예방을 위한 주의사항(useEffect, Event Handler) (1) | 2023.02.14 |
---|---|
[JavaScript] 동기와 비동기적 처리, 콜백 함수 (0) | 2022.12.12 |
[React] 리액트의 특징 : SPA와 CSR, Virtual DOM (0) | 2022.12.10 |
[CSS] flex-grow와 flex-shrink, flex-basis (0) | 2022.12.04 |