상황
input type='file' 태그를 통해서 이미지를 업로드한다.
업로드 하는 위치는 firebase의 storage이고 업로드 진행상황을 progress-bar를 통해 표현하고자 한다.
소스코드
firebase의 uploadBytesResumable 메서드를 통해서 storage에 업로드 된 bytes를 받아올 수 있다.
해당 bytes를 파일의 전체 크기로 나눈 후 100을 곱해주면 진행 퍼센테이지를 알 수 있고,
그 퍼센테이지를 리액트 상태로 관리하면 값이 바뀔 때마다 ui에도 적용되는 것을 볼 수 있다.
css를 통해서 부모인 progress와 자식인 progress-bar 의 배경색을 다르게 하고
progress-bar의 width 값을 uploadProgress 상태값을 받아 오면 실시간으로 채워지는 정도가 달라지게 된다.
import { ref, uploadBytesResumable } from 'firebase/storage'
import { storage } from '@/firebase/firebase'
const [uploadProgress, setUploadProgress]
const handleImageChange = (e) => {
e.preventDefault()
const file = e.target.files[0]
const storageRef = ref(storage, `/images/${Date.now()}${file?.name}`
const uploadTask = uploadBytesResumable(storageRef, file)
uploadTast.on(
'state_changed',
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
setUploadProgress(progress)
},
() => {
// 업로드 된 후 처리
}
)
}
return (
<input type='file' accept='image/*' onChannge={(e) => handleImageChange(e)} />
<div className='progress'>
{uploadProgress === 0
? null
: <div className='progress-bar' style={{ width: `${uploadProgress}%` }}>
// 추가 처리
</div>
}
</div>
)
.progress {
background-color: #aaa;
border: 1px solid transparent;
border-radius: 10px;
}
.progress-bar {
background-color: var(--light-blue);
border: 1px solid transparent;
border-radius: 10px;
color: var(--color-white);
font-size: 1.2rem;
font-weight: 500;
padding: 0 1rem;
}
참고 사이트
아래 firebase 문서에 더 자세한 사항을 확인할 수 있다.
https://firebase.google.com/docs/storage/web/upload-files?hl=ko
'웹' 카테고리의 다른 글
[A non-serializable value was detected in the state] 에러 해결하기 (Redux-toolkit) (0) | 2024.01.22 |
---|---|
이미지 슬라이더 만들기 (React, scss) (0) | 2024.01.17 |
Next Image 사용할 때 주의할 점 (0) | 2024.01.17 |
Redux Toolkit 으로 상태 관리하기 (0) | 2024.01.17 |
리액트에서 토스트 메시지 띄우기 React-Toastify (Next.js) (0) | 2024.01.17 |