🤔 트러블슈팅 (사진 저장 시 , 사진이 하나씩 밀리는 현상 발생)
지난번에 파이어베이스 사진 업로드 기능과 파이어베이스에서 뱉어낸(?)
포토URL을 넣는 과정에서 사진이 앞전 사진으로 하나씩 밀리는 현상이 발생했다.
(localStorage에 앞전에 저장된 포토URL이 들어가는듯했다)
>> 해결한 부분
- state를 새로 만들어, 단순히 localStorage에 사진url이 저장이 되는 onChange 함수에서도 새롭게 만든 state의 set함수를 실행시켜 해당 state 변화를 인지하도록 했다.
// 어떤 state가 업데이트 될때만, 사진저장 메소드가 실행하게 설정하면 되지 않을까?
const [test, setTest] = useState("");
// onFileChange : 사진 업로드 (사진의 onChange이벤트 )
const onFileChange = (event) => {
const theFile = event.target.files[0];
const reader = new FileReader();
console.log("theFile : ", theFile);
reader.readAsDataURL(theFile);
reader.onloadend = (finishedEvent) => {
const imgDataUrl = finishedEvent.currentTarget.result;
localStorage.setItem("imgDataUrl", imgDataUrl);
document.getElementById("boardImg").src = imgDataUrl;
// 일부러 여기서 state 변경을 주기
setTest(imgDataUrl);
};
};
- useEffect를 사용하여 1번에서 만들어놓은 state가 변화될때마다, 파이어베이스에 해당 사진이 저장되고 파이어베이스 메소드에서 url을 받아오는 함수가 실행되도록 설정했다.
// useEffect에서 임의로 만든 state가 업뎃될때만 실행되게
useEffect(() => {
uploadImg();
console.log("test가 업데이트 되었습니다.");
}, [test]);
<<해당 전체코드>>
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { v4 as uuidv4 } from "uuid";
import { __postBoards } from "../../../redux/modules/boardSlice";
import { useNavigate } from "react-router-dom";
import { storage } from "../../../firebase";
import { ref, uploadString, getDownloadURL } from "firebase/storage";
import styled from "styled-components";
const BoardInput = () => {
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const [user, setUser] = useState("");
const [pw, setPW] = useState("");
// 어떤 state가 업데이트 될때만, 사진저장 메소드가 실행하게 설정하면 되지 않을까?
const [test, setTest] = useState("");
const [fireURL, setFireURL] = useState("");
// useEffect에서 임의로 만든 state가 업뎃될때만 실행되게
useEffect(() => {
uploadImg();
console.log("test가 업데이트 되었습니다.");
}, [test]);
const dispatch = useDispatch();
const navigator = useNavigate();
// title change
const onTitleChange = async (e) => {
setTitle(e.target.value);
};
// content change
const onContentChange = (e) => {
setContent(e.target.value);
};
// user, pw change
const onUserChange = (e) => {
setUser(e.target.value);
};
const onPWChange = (e) => {
setPW(e.target.value);
};
// onsubmitHandler
const onSubmitHandler = (e) => {
// 새로고침 방지
e.preventDefault();
// 입력칸 공백 방지
if (!title || !content || !user || !pw) {
alert("제목과 내용 모두 입력하세요");
return;
}
// uploadImg();
const newBoard = {
id: uuidv4(),
user: user,
pw: pw,
title: title,
content: content,
// ImgUrl 추가
ImgUrl: fireURL,
};
console.log("newBoard:", newBoard);
console.log("fireURL:", fireURL);
dispatch(__postBoards(newBoard));
setTitle("");
setContent("");
setUser("");
setPW("");
navigator("/");
};
//-----------------------------------------------------
// uploadImg : 사진 추가 메소드
const uploadImg = () => {
const imgRef = ref(storage, `images/${uuidv4()}`);
const imgDataUrl = localStorage.getItem("imgDataUrl");
let downloadUrl;
if (imgDataUrl) {
uploadString(imgRef, imgDataUrl, "data_url")
.then((response) => {
downloadUrl = getDownloadURL(response.ref).then((response) => {
setFireURL(response);
console.log("uploadImg메소드 실행");
console.log("FireURL : ", fireURL);
});
})
.catch((error) => {
console.log("error", error);
});
}
};
//----------------------------------------
// onFileChange : 사진 업로드 (사진의 onChange이벤트 )
const onFileChange = (event) => {
const theFile = event.target.files[0];
const reader = new FileReader();
console.log("theFile : ", theFile);
reader.readAsDataURL(theFile);
reader.onloadend = (finishedEvent) => {
const imgDataUrl = finishedEvent.currentTarget.result;
localStorage.setItem("imgDataUrl", imgDataUrl);
document.getElementById("boardImg").src = imgDataUrl;
// 일부러 여기서 state 변경을 주기
setTest(imgDataUrl);
};
};
return (
<div>
<form onSubmit={onSubmitHandler}>
<input
type="text"
id="user"
value={user}
onChange={onUserChange}
placeholder="닉네임"
/>
<input
type="password"
id="pw"
value={pw}
onChange={onPWChange}
placeholder="비밀번호"
/>
<input
type="text"
id="title"
value={title}
onChange={onTitleChange}
placeholder="제목을 입력해주세요"
/>
<textarea
id="content"
value={content}
onChange={onContentChange}
placeholder="내용을 입력해주세요"
/>
<div id="imgUrl"></div>
<button>글 등록하기</button>
{/* // --------------------------------- */}
<ImgBox src="/image.jpg" id="boardImg" alt="boardImg" />
<input type="file" onChange={onFileChange} />
{/* // ---------------------------------- */}
</form>
</div>
);
};
export default BoardInput;
const ImgBox = styled.img`
width: 100px;
height: 100px;
`;
댓글