리뷰기능 만들기(3)

라형선·2023년 8월 27일
0


글작성자가 리뷰를 작성하면 DB에 저장되지 않는다.

상대방이 리뷰를 작성하면 DB에 저장된다.

  const opponentuid = tochattingBoxUid;

값이 제대로 설정이 안되있었기 때문에 글작성자가 리뷰를 작성하면 저장이 되지 않는 것이였다.

      await setDoc(
        doc(
          dbService,
          'ChattingUsers',
          `${item.opponentUserUid}`,
          'chattingListroom',
          `${item.reviewRoomId}`
        ),
        {
          ...item,
          nickname: UID.mynickname,
          reviewRoomId: item.reviewRoomId + 'opponent',
           opponentUserUid: item.uid,
        }
        
        ------------------------------------------------------
              await setDoc(
        doc(
          dbService,
          'ChattingUsers',
          `${item.uid}`,
          'chattingListroom',
          `${item.reviewRoomId}`
        ),
        {
          ...item,
          reviewRoomId: item.reviewRoomId + 'poster',
          opponentUserUid: item.opponentUserUid
        }

opponentsUid: item.opponentUserUid
opponentsUid: item.uid
각각 설정해줌으로써 데이터가 제대로 저장해 보았다.

[
    { option: '친절하고 매너가 좋아요', count: 0 },
    { option: '재미있어요', count: 0 },
    { option: '자상하고 편안했어요!', count: 0 },
    { option: '대화의 폭이 넓었어요!', count: 0 },
    { option: '시간약속을 잘 지켰어요', count: 0 },
  ]

기존의 데이터가 있으면 새로운 값이 저장됬지만 기존의 값이 없으면 데이터가 저장되지 않았다.

      userReview?.map((item: { option: string; count: number }) => {
        selectedReview?.forEach((t: string) => {
          if (item.option === t) {
            item.count++;
          }
        });
      });
      setUpdatedReview(() => userReview);
      console.log('updatedUserReview', userReview);
      console.log('path1');
      console.log('handleReviewStateSupdatedReview', updatedReview);

방법은 2가지이다.
1. handleReviewState(중요한 것은 setUpdatedReview)가 updateDoc보다 먼저 실행되게 하는것
1) userReview?.map를 변수에 담는것
2) return을 하여야 하는가?(차이 없다.)

   if (opponentReviewListduplicated?.review === undefined) {
     const newReview = userReview?.map(
       (item: { option: string; count: number }) => {
         selectedReview?.forEach((t: string) => {
           if (item.option === t) {
             item.count++;
           }
         });
       }
     );
     setUpdatedReview(() => newReview);
     console.log('updatedUserReview', userReview);
     console.log('path1');
     console.log('handleReviewStateSupdatedReview', updatedReview);

새로운 변수에 담아서 useState에 저장하고 updateDoc을 해주려고 하면 여전히 오류가 떴다.

batchupdate로 값이 늦게 저장되기 때문 () => newReview 즉시실행 함수를 사용해 봤지만 별 수확이 없었다.

  1. AuthStateListener에서 user에대한 정보를 처음저장할 때 review값을 넣는 방법이다.

1번의 방법은 여러방법을 해보았지만 해결될기미가 보이지 않았기에 2번의 방법을 택했다.

if (Array.isArray(opponentReviewListduplicated?.review))의 Array.isArray는 없어도 잘 작동된다.

useEffect(() => {
handleReviewState();
}, [opponentReviewList]);
useEffect가 없으면 작동되지 않는다.

if (updatedOpponentReveiwList === undefined) return;
await handleReviewState();
console.log('getdoctest2:', opponentReviewList);
console.log('test2:', updatedReview);
await updateDoc(doc(dbService, 'user', getmessage[0].opponentsUid), {
review: updatedReview,
}).then(() => {
console.log('getdoctest3:', opponentReviewList);
console.log('test3:', updatedReview);
});
})
handleReviewState();이 없으면 작동되지 않는다.
handleReviewState() 앞의 await는 실행에 영향을 주지 않는다.

useEffect(() => {
    handleReviewState();
  }, [opponentReviewList]);

이 코드는 왜 꼭 필요한 걸까?

 useEffect(() => {
    if (!roomId) return;
    getChatting();
    handleUserInfo();
  }, [roomId]);

채팅리스트의 리뷰방을 클릭하면 리뷰방의 내용과 상대방의 리뷰리스트를 불러온다.하지만 handleUserInfo();는 비동기적으로 작동하기 때문에 곧바로 데이터를 저장하지 않는 것 같다.

리액트에서 상태 업데이트 함수(setState 또는 useState의 업데이트 함수)는 비동기적으로 동작하며, 업데이트가 완료되고 컴포넌트가 리렌더링된 후에 새로운 상태로 작업을 수행하도록 하기 위해 이와 같은 패턴을 사용합니다. 따라서 상태 업데이트 후에 이어지는 작업을 보장하려면 리렌더링 이후에 작업을 수행하는 방식이 필요합니다.
그래서 useEffect 훅이 사용되는데, 이 훅은 컴포넌트가 렌더링되거나 상태가 변경될 때 실행되는 함수를 등록하는 데 사용됩니다.

그렇다면 getChatting()은 어째서 바로 작동하는가? firebase의 querysnapshot기능 때문일까? 그래서 handleUserInfo()도 onsnapshot으로 바꿔서 실행해 보았다.

 const handleUserInfo = async () => {
    // const docRef = doc(dbService, 'user', opponentuid);
    // const docSnap = await getDoc(docRef);
    const q = query(
      collection(dbService, 'user'),
      where('id', '==', opponentuid)
    );
    onSnapshot(q, (querySnapshot) => {
      const getreview = querySnapshot.docs.map((doc) => {
        const review = {
          id: doc.id,
          ...doc.data(),
        };
        return review;
      });
      setOpponentReviewList(() => getreview);
    });
    console.log('getdoctest1:', opponentReviewList);
    console.log('test1:', updatedReview);
  };

useEffect를 지우고 실행해보았지만 undefined가 나왔다.

  useEffect(() => {
    if (!roomId) return;
    getChatting();
  }, [roomId]);

  useEffect(() => {
    if (!roomId) return;
    handleUserInfo();
  }, [roomId]);

=>결론 getDoc도 onSnapshot도 데이터를 곳바로 저장한다.

useEffect(() => {
    handleReviewState();
  }, [opponentReviewList]);
  
  =======================================================
  
  if (updatedOpponentReveiwList === undefined) return;
         handleReviewState();
        console.log('getdoctest2:', opponentReviewList);
        console.log('test2:', updatedReview);
        await updateDoc(doc(dbService, 'user', getmessage[0].opponentsUid), {
          review: updatedReview,
        }).then(() => {
          console.log('getdoctest3:', opponentReviewList);
          console.log('test3:', updatedReview);
        });
      })

useEffect로 handleReviewState() 불러오고

update할때에도 handleReviewState()를 불러오는 것이 핵심

완성된 리뷰기능

profile
형선

0개의 댓글