출근을 앞두고 오랜만에 쉬느라 업로드를 하지 못했다...
다시 업로드 해야지ㅎㅎ
텍스트를 최대한 배제한 일기 쓰는 사이트를 만들고 있다.
클릭을 이용해서 최대한 손이 덜 가게 하는 프로젝트임.
백엔드 없이 프론트만으로 구현하기 때문에 서버는 파이어베이스를 사용했다.
이미지를 업로드하고 다운로드할 수 있어야 한다.
이미지를 업로드를 하는 기능을 만들것이다.
// writePage.tsx
const storage = getStorage(firebaseApp);
const storage = getStorage(firebaseApp);
const [imageUpload, setImageUpload] = useState<any>("");
const [image, setImage] = useState("");
const fileRef = useRef<HTMLInputElement>(null);
input
에서 파일들을 가져오기 위한 state
는 imageUpload
로 이미지를 다운로드해서 url을 저장할 state
는 image
로 받아왔다.
useRef
는 div
를 클릭해도 input
이 실행될 수 있게 해주는 훅이다.
const storage = getStorage(firebaseApp);
const [imageUpload, setImageUpload] = useState<any>("");
const [image, setImage] = useState("");
const fileRef = useRef<HTMLInputElement>(null);
// div를 클릭해도 input이 클릭되도록 하기
const onClickUpload = () => {
fileRef.current?.click();
};
// input클릭해서 파일 업로드 해주기
const onChangeUpload = (event: ChangeEvent<HTMLInputElement>) => {
setImageUpload(event.target.files?.[0]);
};
// 파일이 업로드 되었으면 스토리지에 업로드하고 다운 즉시 이미지 보여주는 함수
useEffect(() => {
// 스토리지의 주소를 알려주기 위해서 ref를 파이어베이스에서 임포트해오고 imageRef라는 변수에 담았다.
const imageRef = ref(storage, `${userAuth.currentUser?.uid}/${datePick}`);
if (!imageUpload) return;
uploadBytes(imageRef, imageUpload).then((snapshot) => {
getDownloadURL(snapshot.ref).then((url) => {
setImage(url);
});
});
}, [imageUpload]);
useEffect
를 통해서 imageUpload
가 변경되면 즉 input
을 클릭해서 업로드를 하면 스토리지 주소를 참조하고 스토리지에 로그인한 아이디의 uid/날짜
형식으로 업로드 하게 해주었다.
업로드가 종료되면 uploadBytes
를 통해서 스토리지에 이미지 url을 다운받아서 렌더링 될 수 있도록 함.
가->나->다 순으로 함수를 구현하였다.
이후 컴포넌트에 props를 내려주어 업로드가 될 수 있도록 구현 하면 된다.
마이페이지에 들어가면 이미지를 불러오기를 해야 한다.
// ListItem.tsx
const storage = getStorage(firebaseApp);
const storage = getStorage(firebaseApp);
const [image, setImage] = useState<any>("");
const imageRef = ref(storage, `${props.userAuth.currentUser?.uid}/`);
파이어베이스에서 ref
를 임포트해서 스토리지 주소를 알려준다.
현재 스토리지 주소 이름은 로그인한 유저의 uid
이다.
const storage = getStorage(firebaseApp);
const [image, setImage] = useState<any>("");
const imageRef = ref(storage, `${props.userAuth.currentUser?.uid}/`);
useEffect(() => {
listAll(imageRef).then((response) => {
response.items.forEach((item) => {
getDownloadURL(item).then((url) => {
if (url === props.el.image) {
setImage(url);
}
});
});
});
}, []);
파이어베이스에서 listAll
을 임포트해서 이미지를 다운받아온다.
파이어베이스 공홈에 docs를 참조하기 바람.
getDownloadURL
로 다운이 완료되었으면 url과 일기 데이터의 image
가 같은 경우에 image state
에 url을 담아준다.
<div style={{
backgroundImage: `url(${image})`,
backgroundSize: "cover",
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
}}>
블라블라~~
</div>
가->나->다->라 순으로 완성하면 기능이 구현이 된다.
파이어베이스 이거 은근히 쉬울 지도?