Twitter 클론코딩 5.Firebase : Data Fetching

<angeLog/>·2024년 4월 1일

REACT

목록 보기
24/25
post-thumbnail

TypeScript Interface

이런게 있다고 한다. 그냥 변수에 타입을 선언한 것 같은데 vue로 치면 return에 data를 명시해준...? 그런 것 같다.
리액트 공부하는데 vue같은게 등장할 때마다 비슷하단 생각이 들어서 계속 흠칫하게 됨...

export interface Itweet {
  id: string;
  imgUrl?: string;
  tweet: string;
  userId: string;
  userName: string;
  creatAt: number;
}

이거 안쓰고 데이터 바인딩 해보려고 했는데 계속 오류가 난다.
타입스크립트를 잘 몰라서 생기는 문제라고 밖에 생각이 안드는데 진짜 공부해야할 것 같다...
내가 싫어한다고 해도 다수가 사용한다면 그만한 이유가 있는 것이니께.

문서 가져오기

①단일문서 가져오기 (실패)

const fetchTweet = async () => {
  const docRef = doc(db, 'tweets');
  const docSnap = await getDoc(docRef);
  if (docSnap.exists()) {
    console.log('Document data : ', docSnap.data());
  } else {
    console.log('No data');
  }
};

문서를 참고하여 데이터를 가져올 코드를 작성해 보았지만 왜인지 데이터를 가져오지 못했다.
다양한 방법들이 제시되어 있었기 때문에 바로 다른 방법들을 시도해 보았다.

②커스텀 객체 가져오기 (실패)

일단 문법 자체를 이해하지도 못했기 때문에 당연히 에러가 나온다.

+추가
TypeScript문법같다. 추후에 타입스크립트 공부를 어느정도 하고 나면 이 방법으로 시도해봐야겠다.

③컬렉션에서 여러 문서 가져오기 (실행안함)

where이 뭔지 모르기도 했고, 바로 다음에 나온 where없이 실행하는 방법이라 건너뛰었다.

④컬렉션의 모든 문서 가져오기 (성공)

await가 있어서 async로 묶어줬다.

const fetchTweet = async () => {
  const querySnapshot = await getDocs(
    collection(db, 'tweets')
  );
  querySnapshot.forEach((doc) => {
    // doc.data() is never undefined for query doc snapshots
    console.log(doc.id, ' => ', doc.data());
  });
};

콘솔에 원하는대로 데이터가 보여진다!
doc.data()를 활용해서 데이터를 바인딩 하면 될 것 같다.

const [tweet, setTweet] = useState<Itweet[]>([]);

const fetchTweet = async () => {
  const querySnapshot = await getDocs(
    collection(db, 'tweets')
  );
  querySnapshot.forEach((doc) => {
    const { creatAt, imgUrl, tweet, userId, userName } =
          doc.data();
    return {
      creatAt,
      imgUrl,
      tweet,
      userId,
      userName,
      id: doc.id,
    };
  });
  setTweet(tweet);
  console.log('tweet', tweet);
};

아무것도 보여지지 않는다. forEach로는 데이터 상태를 관리할 수 없나보다.
forEac와 비슷해보이지만 Array를 반환해주는 map()을 써보기로 했다.

const fetchTweet = async () => {
  const tweetQuery = query(
    collection(db, 'tweets')
  );
  const querySnapshot = await getDocs(tweetQuery);
  const tweet = querySnapshot.docs.map((doc) => {
    const { creatAt, imgUrl, tweet, userId, userName } =
          doc.data();
    return {
      creatAt,
      imgUrl,
      tweet,
      userId,
      userName,
      id: doc.id,
    };
  });
  setTweet(tweet);
  console.log('tweet', tweet);
};

콘솔에 데이터가 잘 찍혔다.

데이터를 정렬하는 기능도 존재했다.
Firestore에 만든 콜랙션의 creatAt을 이용해서 sort하면 될 것 같다.

데이터 정렬하기

query를 쓸 때 사용하면 되는 것 같다.
내림차순을 할 것이니 orderBy를 추가했다.

const tweetQuery = query(
  collection(db, 'tweets'),
  orderBy('creatAt', 'desc')
);

styled component를 만들고 데이터를 바인딩했다.

return (
  <Wrapper>
  {tweet.map((tweet) => (
  <Tweet key={tweet.id} {...tweet} />
))}
  </Wrapper>
);

데이터 바인딩까지 잘 되었지만 새로 tweet했을 땐 새로고침 해야만 새글이 보여진다.
당연하다, 스테이트가 바뀔 때마다 데이터를 가져올테니깐...

useEffect(() => {
  fetchTweet();
}, [tweet]);

여기까지 하면 tweet할 때마다 페이지의 데이터를 화면에 뿌려준다.
but 다음 강의에 실시간트윗 기능 배울 차례라 이것은 주석하는 것으로 마무리.

profile
일단 해볼게요!✍🏻

0개의 댓글