일기를 적을 수 있는 폼이 준비되었으니 만들어 둔 폼을 필요한 형식을 갖추어 구현해야한다.
폼에는 일기 제목, 날짜, 사진, 내용이 들어갈 예정이다.
현재 있는 폼에는 예전에 작업해둔 제목, 내용과 모달 작업을 할때 추가한 날짜부분이 구현되어 있어 사진 인풋을 추가하고 사진을 파이어 베이스에 추가하는 작업을 해보려고 한다.
인풋을 넣는것은 어렵지 않지만 인풋창을 디자인이랑 어울리게 커스텀하기 위해 못생긴 인풋창은 숨겨주고 가짜 인풋을 만들어 useRef
를 사용해 연결시켜보기로 했다.
const fileInputRef = useRef();
const fildInputClickHandler = () => {
fileInputRef.current.click();
};
.
.
.
<label htmlFor='file'>show your day : </label>
<input
id='date'
type='file'
ref={fileInputRef}
style={{ display: "none" }}
/>
<div onClick={fildInputClickHandler}>🎬</div>
이제 전달된 사진을 화면에도 출력해주는 작업을 해주어야한다!
왠지 useState를 활용하면 쉽게 할 수 있을것 같다✨
그냥 단순하게 생각하고 바로 시도해봤더니 1차 시도는 처참히 실패했다.
const [photo, setPhoto] = useState("");
<input
id='date'
type='file'
ref={fileInputRef}
value={photo}
onChange={() => {
setPhoto(fileInputRef.current.value);
console.log(fileInputRef);
console.log(photo);
}}
style={{ display: "none" }}
/>
<div
onClick={fildInputClickHandler}
style={{
backgroundImage: `src(${photo})`,
width: "100px",
height: "100px",
}}
>
🎬
</div>
첫번째 콘솔을 보면 input자체에는 사진이 올라갔는데 useState에는 들어가지 않았다....!빈값이 찍히는걸보니 읽어오지를 못하는것 같았고, vanillaJS에서 사용했던 fileReader가 생각이 났다.
FileReader
웹 어플리케이션이 비동기적으로 데이터를 읽기 위해 읽을 파일인 file 혹은 blob 객체를 이용해 파일의 내용을 읽고 사용자의 컴퓨터에 저장하는 것을 가능하게 해줍니다.
MDN
fileReader를 사용하는 이유는 코드단에서 이미지 데이터를 저장하고 사용하기 위해서는 base64로 출력 형식을 변환해줘야 하는데 이 부분을 fileReader가 해결해 줄 수 있기 때문이다.
<input
id='date'
type='file'
ref={fileInputRef}
onChange={(e) => {
fileHandler(e.target.files[0]);
}}
style={{ display: "none" }}
/>
<div
onClick={fildInputClickHandler}
style={{
width: "100px",
height: "100px",
}}
>
🎬
{photo !== "" && <img src={photo} alt='upload image' />}
</div>
const fileHandler = (file) => {
const reader = new FileReader();
reader.readAsDataURL(file);
return new Promise((res) => {
reader.onload = () => {
setPhoto(reader.result);
res();
};
});
};
fileHandler의 코드를 우선 살펴보자면
reader.readAsDataURL(file)
을 통해 매개변수로 받아온 file을url 형식으로 읽어주고, 데이터를 모두 읽으면 실행되는 onload함수에서 읽어온 데이터의 result를 setPhoto에 할당해주었다.
과연...
두둥!
이제 진짜 css하고 파이어베이스에 저장만 하는것까지하면 끝이 보일지도...!?
우선 이렇게 css작업까지 완료!
이제 이 데이터들을 파이어베이스에 추가하면 되는데,,,,
미리 만들어둔 커스텀 훅에 추가까지 했는데,,,
파이어베이스에 올라가지않았다! 두둥.... 왜그런거지!
콘솔에 찍어보며 추적해 올라가보니 커스텀 훅 내에서 파라미터가 찍히지 않았다!
왜그런지 함수들을 계속해서 타고 올라가보니 로그인 하면 받아와지는 user의 uid를 함수에 넘겨주어야하는데, 리팩토링을 거치면서 해당 함수들을 옮겨주지 않았고 정신차려 나자신! 그래서 함수의 동작이 막혔던것이다!
필요한 함수들을 옮겨주고 나니 정상적으로 파이어스토어에 찍히기 시작했다!!
이제 찍혀진 데이터를 달력의 background로 가져오면 완성이다 !
stay tuned!
자세한 코드는 깃헙으로 놀러오세요🙌