yamoo9 / likelion-FEQA

질문/답변 — 프론트엔드 스쿨, 멋사
29 stars 9 forks source link

[LAB-3] 데이터가 존재하지 않을 때 띄우는 메세지의 렌더링 시점을 어떻게 조절해야하는 지 모르겠습니다. #236

Closed eeeyooon closed 1 year ago

eeeyooon commented 1 year ago

질문 작성자

강지윤

문제 상황

현재 작업하는 부분이 로그인한 사용자가 작성한 리뷰만 화면에 보여주는 것인데, 사용자가 작성한 리뷰가 없을 경우 "작성한 리뷰가 없습니다."라는 메세지를 띄우고 있습니다.

  const userReview = reviews.filter((value) => value.userId === userId);

userReview는 DB에서 리뷰데이터를 모두 담은 reviews에서, 로그인한 유저의 아이디가 포함된 리뷰 데이터만 가져와 담는 변수입니다. 이 userReviewlength가 0보다 크면 리뷰를 보여주고 0일 때는 "작성한 리뷰가 없습니다."를 띄우도록 코드를 작성했습니다.


  const showReviews = () => {
    if (userReview.length > 0) {
      return userReview
        .sort((a, b) => b.date - a.date)
        .map((value) => (
          <ReviewBoxWrapper key={value.id}>
            <ReviewBoxHeader>
              <ParkingLot>파킹 주차장</ParkingLot>
              <BtnWrapper>
                <ReviewUpdateButton
                  className="btnUpdate"
                  onClick={() => {
                    isEdit(value.id, value.userId, value.content, value.recommend);
                  }}
                />
                <ReviewDeleteButton
                  onClick={() => {
                    deleteReview(value.id, value.name);
                  }}
                />
              </BtnWrapper>
            </ReviewBoxHeader>
            <ReviewWrapper>
              <ReviewInfo>
                {value.recommend ? <RecommendTag /> : <NotRecommendTag />}
                <p className="reviewDate">{new Date(value.date).toLocaleString()} </p>
              </ReviewInfo>
              <ReviewContent>{value.content}</ReviewContent>
            </ReviewWrapper>
          </ReviewBoxWrapper>
        ));
    } else {
      return <NoReview>작성한 리뷰가 없습니다.</NoReview>;
    }
  };

다만 이렇게 하면 리뷰가 존재하더라도, 처음 userReview를 선언 후 DB에서 리뷰 데이터를 가져와 userReview에 저장하기 전 그 시점에 "작성한 리뷰가 없습니다."라는 메세지가 뜨고 그 이후에야 리뷰가 보입니다.

메세지뜨는시점

위 gif에 콘솔엔 console.log(userReview.length);를 찍은 것입니다. 리뷰 데이터가 저장되기 전, userReview가 선언만 됐을 때 렌더링이 돼서 문제가 발생한 것 같은데 여러 방법을 써보고 훅을 써봐도 해결 방법을 모르겠습니다. ㅠㅠ

프로젝트 저장소 URL

환경 정보

yamoo9 commented 1 year ago

당부의 말

해당 질문은 로그인 해야 리뷰 글을 데이터베이스에서 불러와 테스트 해볼 수 있겠죠? 그러므로 테스트 계정 정보를 알려줘야 합니다. 하지만 Google 계정 로그인만 가능하다는 점에서 계정 공유도 어려울 것입니다. 이런 경우, 테스트 라우트(route)에 연결될 페이지 컴포넌트와 더미 로그인 사용자 정보를 포함하는 컴포넌트를 제공했다면 답변하기 용이 했을 겁니다. 😳

문제 해결

리뷰 로딩(loading) 상태를 추가해 관리해보세요. 😃 데이터베이스에서 사용자 리뷰 정보를 모두 가져온 후에 로딩 상태를 변경하면 "작성한 리뷰가 없습니다." 대신 "작성한 리뷰 로딩 중..."을 띄울 수 있을 것입니다.

// [상태] 리뷰 로딩
const [loading, setLoading] = useState(true);

// [사이드 이펙트] 데이터베이스 → 리뷰 요청/응답
useEffect(() => {
  const getReviews = async () => {
    try {
      const reviewsCollectionRef = collection(db, 'reviews');
      const data = await getDocs(reviewsCollectionRef);
      setReviews(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
    } finally {
      // 리뷰를 모두 받은 경우, 로딩 상태 false로 변경
      setLoading(false);
    }
  };

  getReviews();
}, []);

// 로딩 이전 시점까지 로딩 스피너 화면에 표시
if (loading) {
  return <ReviewLoading>작성한 리뷰 로딩 중...</ReviewLoading>
}