Notice
Recent Posts
Recent Comments
Link
프로그래밍 공부방
[Next.js] 리뷰 구현 중 생긴 문제점과 해결방법 본문
🙀문제점
👉문제 내용
리뷰창을 띄운 후 리뷰를 작성할 수 있게 하는 기능을 구현하던 중에 생긴 문제가 생겼습니다.
리뷰 창에 별점을 줄 수 있는 기능이 있었는데 별점이 달라질 때마다 리뷰창이 사라졌습니다.
👉문제 원인
리뷰 점수 설정과 리뷰창 상태를 useState()로 설정을 해놨기 때문에 별점이 달라질 때마다 리렌더링되어서 리뷰창이 사라지는 것이었습니다.
const [reviewState, setReviewState] = useState("false"); // 리뷰창 상태
const [reviewScore, setReviewScore] = useState(1); // 리뷰 점수코드 작성
✨해결 방법
리뷰창의 상태를 useState()만으로 설정하지 않고 localstorage에도 저장해주는 방식으로 문제를 해결했습니다.
const ChatDetail: NextPage = () => {
const { user } = useUser();
const [reviewState, setReviewState] = useState("false"); // 리뷰창 상태
const [reviewScore, setReviewScore] = useState(1); // 리뷰 점수
useEffect(() => {
socket.on("review", (msg: any) => {
if (user?.id === msg) {
localStorage.setItem("reviewState", "true");
setReviewState("true");
}
});
return () => {
socket.off("review");
localStorage.removeItem("reviewState");
};
}, [user]);
useEffect(() => {
if (data?.ok) {
localStorage.setItem("reviewState", "false");
setReviewState("false");
}
}, [data]);
useEffect(() => {
let state = localStorage.getItem("reviewState");
if (!state) return;
setReviewState(state as string);
});
const preventClose = (e: BeforeUnloadEvent) => {
localStorage.setItem("reviewState", "false");
};
useEffect(() => {
(() => {
window.addEventListener("beforeunload", preventClose);
})();
return () => {
window.removeEventListener("beforeunload", preventClose);
};
}, []);
return (
<>
{reviewState === "true" ? (
<div
className={cls(
"flex flex-col justify-center items-center fixed left-0 top-0 z-10 h-screen w-full bg-black/[0.7]",
reviewState === "true" ? "" : "hidden"
)}
>
<form
onSubmit={handleSubmit(onValid)}
className="bg-orange-500 w-10/12 max-w-xl h-full max-h-[500px] p-5"
>
<h1 className="text-gray-200 font-bold text-center text-xl pb-3">
거래 후기를 남겨주세요
</h1>
<div className="flex h-1/6">
{[1, 2, 3, 4, 5].map((star, i) => (
<svg
key={star}
className={cls(
"h-full w-16",
reviewScore >= star ? "text-yellow-400" : "text-gray-400"
)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
stroke="#000000"
onClick={() => {
setReviewScore(i + 1);
}}
>
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
</svg>
))}
</div>
<textarea
placeholder="후기 작성"
className="w-full h-1/2 resize-none outline-none px-3 py-2"
{...register("review", { required: true, minLength: 1 })}
/>
<button className="w-full bg-orange-300 hover:bg-orange-400 text-white px-4 py-3 text-base border border-transparent rounded-md shadow-sm font-medium focus:ring-2 focus:ring-offset-2 focus:ring-orange-500 focus:outline-none mb-2">
등록
</button>
<button
className="w-full bg-gray-400 hover:bg-gray-500 text-white px-4 py-3 text-base border border-transparent rounded-md shadow-sm font-medium focus:ring-2 focus:ring-offset-2 focus:ring-orange-500 focus:outline-none"
onClick={() => {
localStorage.setItem("reviewState", "false"); // localstorage에도 reviewState 저장
setReviewState("false");
}}
>
취소
</button>
</form>
</div>
) : null}
</>
);
};
localstorage에 리뷰상태를 저장하고 useState의 reviewState 변수에 해당 값을 넣어주기 때문에,
localstorage에 계속 값이 true로 남아있으면 다른 채팅창을 들어가도 review창이 뜨는 문제가 발생할 수 있습니다.
useEffect(() => {
let state = localStorage.getItem("reviewState");
if (!state) return;
setReviewState(state as string);
});
따라서 unmount될 때 localstorage에 있는 reviewState값을 제거하도록 설정해주었습니다.
👉 useEffect()의 return() 안에 들어가는 코드는 [ ] 안에 있는 값이 달라지거나 해당 component가 unmount될 때 실행됩니다.
useEffect(() => {
socket.on("review", (msg: any) => {
if (user?.id === msg) {
localStorage.setItem("reviewState", "true");
setReviewState("true");
}
});
return () => {
socket.off("review");
localStorage.removeItem("reviewState");
};
}, [user]);
✨ 결과물
별점을 바꿔줘도 리뷰창이 변화없이 잘 떠있는 것을 확인할 수 있습니다!
'프론트엔드 > Next.js' 카테고리의 다른 글
[Next.js] 환경변수 오류 (0) | 2023.06.22 |
---|---|
[EmailJS] Next.js에서 이메일 보내는 기능 구현 (0) | 2023.06.22 |
[Next.js] socket.io를 vercel에 배포하면서 생긴 문제점 해결 과정 (0) | 2023.06.20 |
[Next.js] vercel에서 aws s3 사용 방법 (0) | 2023.06.19 |
[Next.js] router.push와 router.replace 차이점 (0) | 2023.05.02 |
Comments