아래와 같은 이전 예약 리스트 조회 화면에서 각 예약 내역 옆에 있는 ‘리뷰 남기기’ 버튼을 누르면 모든 예약 내역 아래에 리뷰 등록 폼이 등장하는 문제가 발생했다.😱
버튼 클릭시isOpen
값이false
→true
로 바뀌도록 설정을 해놨기 때문에 모든 예약 내역 아래 리뷰 등록 폼이 등장할 수 밖에 없었던 것이다..
에러 원인은 아주 잘 알고 있었지만 이것을 어떻게 해결해야 할지 해결 방법이 떠오르지 않았댜,,
id을 이용해서 구현하면 될 것 같긴 한데 이를 어떻게 활용해서 구현할지 막막했달까나 🥲
구현 로직에 대해 구글링하고, 코드를 계속 수정해나가다가 map() 안에서 item을 어떻게 숨기고, 보여줘야 하는가에 대한 stackOverFlow의 한 질문의 답변을 참고하여 코드를 수정했더니 리뷰 등록 폼이 하나의 예약 내역에서만 보여졌다!
그러나 다른 문제는 리뷰 등록 폼이 열린 상태에서 같은 버튼을 다시 클릭했을 때 폼이 사라지지 않는다는 것이다,, 이것은 id가 일치할 때 즉, 같은 버튼을 또 눌렀을때isOpen
을false
로 바꿔주니까 내가 원하는대로 잘 작동이 되었다. 🙌
🔗 [이슈 해결에 도움을 준 참고 자료쓰] How to show/hide an item of array.map()?
// RezItem.js (리뷰 남기기 버튼이 있는 각 예약 내역 아이템)
const RezItem = ({ item, openReviewHandler }) => {
const { pathname } = useLocation();
return (
<div>
<ItemBox>
...
<ButtonBox>
<BasicBtn
onClick={
pathname === "/client/mypage/rez"
? null
: () => openReviewHandler(item.id)
}
>리뷰 남기기</BasicBtn>
</ButtonBox>
</ItemBox>
<hr />
</div>
);
};
export default RezItem;
// MyPastRezBox.js (이전 예약 내역 리스트)
import PostReview from "../atoms/PostReview"; // 리뷰 등록 폼
const MyPastRezBox = () => {
const [isOpen, setIsOpen] = useState("");
const openReviewHandler = (id) => {
// isOpen을 true/false로만 설정하려고 했던게 문제였음..
// isOpen 값 자체에 id를 담기
// isOpen과 id가 같지 않을 때 버튼 누른 예약 내역 id로 변경
setIsOpen((el) => (el.isOpen !== id ? id : ""));
// 이미 리뷰 등록 폼이 열려있을 때 다시 버튼을 누른 경우
// isOpen 상태를 false로 변경함으로써 리뷰 등록 폼 닫기
if (isOpen === id) {
setIsOpen(false);
}
};
return (
<Container>
{rezData.map((item) => {
return (
<div key={item.id}>
<RezItem item={item} openReviewHandler={openReviewHandler} />
{/* isOpen과 id가 같은 경우에만 리뷰 등록 폼 보여주기 */}
{isOpen === item.id ? <PostReview /> : null}
</div>
);
})}
</Container>
);
};
export default MyPastRezBox;