검색결과에서 상세페이지로 이동시 카카오맵으로부터 상세페이지에 관한 정보를 넘겨받고 있기 때문에 바로 이동이 가능했다. 그러나 리뷰 데이터는 카카오맵이 아닌 파이어스토어의 데이터를 불러오는 것이기에 별도의 작업이 필요했다.
ReviewForm
const addReview = async () => {
await addDoc(collection(dbService, "reviews"), {
contents,
createdAt: Date.now(),
userId: authService.currentUser?.uid,
userNickName: authService.currentUser?.displayName,
detailId: item.id,
date: new Date(),
place_name: item.place_name,
photoUrl: authService.currentUser?.photoURL,
isEdit: false,
address_name: item.address_name,
road_address_name: item.road_address_name,
phone: item.phone,
category_group_name: item.category_group_name,
place_url: item.place_url,
x: item.x,
y: item.y,
});
};
카카오맵 정보를 불러오는 작업은 간단하다. 리뷰 작성시 상세페이지에 필요한 카카오맵 정보를 모두 저장하면 된다. 그러나 예상치 못한 문제가 발생했다.
검색결과 ➡️ 상세페이지 경로로 작성한 리뷰와 메인 or 마이페이지 ➡️ 상세페이지 경로로 작성한 리뷰 데이터가 모두 반환되지 않고 각각의 경로에 해당하는 리뷰만 보여주는 문제다.
원인은 detailId: item.id
였다. 콘솔로 찍어보니 두 경로의 detailId
가 다른 값으로 저장되고 있었던 것이다.
detailId: item.id
를 id: item.id
로 통일하고 메인 or 마이페이지 ➡️ 상세페이지 이동시에도 navigate('/detail/${item.id}'
로 경로를 변경하자 리뷰 데이터가 모두 반환되었다.
그러나 같은 업체에서 여러개의 리뷰를 작성시, 마이페이지에서 해당 업체의 리뷰 수정 버튼을 눌렀을 때 업체에 쓴 다른 리뷰까지 모두 수정 양식으로 변경되는 문제가 발생했다. item.id
는 파이어스토어에 데이터 추가시 생성되는 데이터의 고유 id값이고, id
속성으로 각각의 데이터의 CRUD를 관리하고 있기 때문이었다.
- 메인 or 마이페이지 ➡️ 상세페이지 경로의
item.id
값
파이어스토어 데이터의 고유 id- 검색결과 ➡️ 상세페이지 경로의
item.id
값
카카오맵에서 제공하는 업체 id
두 경로가 제공하는 item.id
값이 다르기 때문에 detailId
속성을 추가해서 해당 속성에 통일된 id값을 넣어줘야 한다.
const item = location.state;
const onNavigate = (item: { detailId: number }) => {
navigate(`/detail/${item.detailId}`, { state: item });
};
메인 or 마이페이지에서 상세페이지로 이동시 해당 데이터를 전달해주고자 했지만 리뷰 컴포넌트에서는 카카오맵 API를 불러올 수 없기 때문에 데이터를 전달할 방법이 없었다.
detailId: location.pathname.slice(8),
한참을 고민하던 도중 예전 프로젝트에서 모달에 url 경로를 부여하기 위해 location.pathname
을 사용했던 기억이 떠올랐다. 리뷰 작성시 위 속성도 함께 추가해서 공통의 detailId
값을 생성했다.
두 번째 방법을 완료하고 나서는 당연히 될 줄 알았는데 검색결과 ➡️ 상세페이지의 경우에만 리뷰를 반환했다. 콘솔로 찍어보니 메인 or 마이페이지 ➡️ 상세페이지 경로에선 빈 배열을 반환했다.
ReviewItem
const item = location.state;
useEffect(() => {
const q = query(
collection(dbService, "reviews"),
orderBy("createdAt", "desc"),
where("detailId", "==", item.id)
);
const unsubscribe = onSnapshot(q, (snapshot) => {
const newReviews: any = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setReviews(newReviews);
});
return unsubscribe;
}, []);
원인은 where("detailId", "==", item.id)
이 부분이었다.
리뷰 데이터의
detailId
에 해당하는 값
- 검색결과 ➡️ 상세페이지:
item.id
- 메인 or 마이페이지 ➡️ 상세페이지:
item.detailId
item.id
에 해당하는 값을 검색결과 ➡️ 상세페이지 경로시에만 충족하고 있기 때문이었다. (공통적인 속성을 줬음에도 왜 두 경로의 속성 이름이 다른 것인지는 잘 모르겠다...)
const filteredId = item.detailId ? item.detailId : item.id;
id
값을 접속 경로에 따라 다르게 설정해서 해당 데이터를 where
문에 적용하자 어떤 경로에서든 모든 리뷰 데이터를 반환할 수 있게 되었다.