[React] new FileReader(), Promise.all()

badassong·2022년 12월 15일
0

React

목록 보기
17/56
post-thumbnail

useEffect에서 setState를 사용하면 추가렌더링이 발생해서 비효율적인 경우가 있으므로 useMemo로 바꿔보자!

이미지 업로드 (임시 URL 생성)

기존 이미지 업로드가 비효율적인 부분 2가지
1. 이미지 찌꺼기가 남는다.
2. 이미지 미리보기가 느리다.

바뀐 이미지 업로드 방식 => 업로드 타이밍 변경!
미리보기를 가짜 url을 임시로 만들어서 보여주고, onClickSubmit할 때 백엔드 요청을 한다!

임시 URL 만들기

1. 첫번째 방법

export default function ImageUploadPreviewPage() {

	const [iamgeUrl, setImageUrl] = useState("")

	****const onChangeFile=(event: ChangeEvent<HTMLInputElement>)=> {
		const file = event.target.files?.[0]
		console.log(file);
			// 파일이 없으면 함수를 종료합니다.
			if (!file) {
				alert("파일이 없습니다.");
				return
			}
		
	// 1. 임시 URL 생성 -> 가짜 URL생성, 내 브라우저에서만 접근 가능
	const result = URL.createObjectURL(file)
	console.log(result)
	setImageUrl(result)
		
}
****	return (
		<>
			<div>
				<input type="file" onChange={onChangeFile}></input>
				<img src={iamgeUrl}/>
			</div>
		</>
	);
}

이렇게 임시 URL을 생성하게 되면, 내 브라우저에서는 URL에 접근이 가능하지만 다른 브라우저에서는 접근이 불가능하다.
그럼, 두번째 방법에서는 다른 브라우저에서도 접근이 가능하도록 만들어주겠다.

2. 두번째 방법

new FileReader()

두번째로는 new FileReader()를 이용하여 진짜 URL을 생성하고, 다른 브라우저에서도 접근이 가능하도록 만들어보도록 하겠다. new FileReader() 기능은 파일 객체를 이용해 내용을 읽고 사용자 컴퓨터에 저장하는 것을 가능하게 해주는 브라우저에서 지원해주는 기능이다.
new FileReader() 를 사용하면 new FileReader() 에 있는 기능들을 이용할 수 있다.

export default function ImageUploadPreviewPage() {

	const [iamgeUrl, setImageUrl] = useState("")

	const onChangeFile=(event: ChangeEvent<HTMLInputElement>)=> {
		const file = event.target.files?.[0]
		console.log(file);
			if (!file) {
				alert("파일이 없습니다.");
				return
			}
		
	// 2. 임시 URL생성 -> 진짜 URL생성, 다른 브라우저에서도 접근 가능	
	const fileReader = new FileReader()
	fileReader.readAsDataURL(file);
	fileReader.onload = (data) => {
		// 파일리더의 결과값이 string이 아닐수도 있으니 string일때만 실행되도록 
		if(typeof data.target?.result === "string"){
			console.log(data.target?.result);
			setImageUrl(data.target?.result)
		}	
	}
}
	return (
		<>
			<div>
				<input type="file" onChange={onChangeFile}></input>
				<img src={iamgeUrl}/>
			</div>
		</>
	);
}

new FileReader() 기능을 const fileReader에 담아주었습니다. 그러면 fileReader는 new FileReader()의 기능을 사용할 수 있다.

그럼 1번과 2번 방법 중 어떤걸 사용해야 할까?
→ 상황에따라 다르다.
2번째 방법은 예전에 나온 기능이라 안정성에 있어서 괜찮지만, 1번 방법은 나온지 얼마 되지 않은 기능이라 지원하지 않는 브라우저가 있을 수 있다.

하지만, 1번 방법은 2번 방법에 비해 간편하다는 이점이 있기 때문에 브라우저를 따져보고 지원한다면, 사용해도 좋다.

⚠️ 다만, 두 방법 모두 스토리지에 업로드는 되지 않기 때문에 찌꺼기가 생기지 않는다는 점에서 유용하다는 것만 숙지하면 된다.

임시 URL을 생성해서 이미지를 업로드하면 이미지가 문자열로 바뀌어서 뜬다.
하지만 이대로 업로드 하면 안된다! 미리보기용으로만 쓰고 db에 넘기면 안됨! 용량이 너무 크고 비효율적이기 때문!

Promise.all

비동기 작업을 병렬로 진행할 때 사용할 수 있는데, async-await를 사용하면 함수를 하나하나 다 기다렸다가 실행하지만, Promise.all을 사용하면 훨씬 시간을 단축시킬 수 있다!!
🚨하지만 Promise.all 내부에서는 태스크들의 순서가 제어되지 않기 때문에 태스크의 순서가 중요한 경우라면 절대 Promise.all을 통해 관리해서는 안된다!!

Promise.all 사용

페이지 성능 개선하기

  1. lazy-load
  2. webp 확장자 파일 사용(webp 이미지 파일을 사용하면 속도가 훨씬 빨라진다!)
  3. page-speed-insight
  4. preload
  5. prefetch

react-dropzone
react-avatar-editor
react-beautiful-dnd(트렐로)
wappalyzer 크롬
코드너리 접속해보기!


profile
프론트엔드 대장이 되어보쟈

0개의 댓글