๐ŸŒŸ ์ด์ฏค์—์„œ ์ฝ”๋“œ ์ •๋ฆฌํ•˜๊ณ  ๊ฐ€๊ธฐ

summereuna๐Ÿฅยท2022๋…„ 6์›” 9์ผ

๐ŸŒŸ Twinkle (React, Firebase)

๋ชฉ๋ก ๋ณด๊ธฐ
27/42

ํด๋ฆฐ ์ฝ”๋“œ๋ฅผ ์‹ค์ฒœํ•ด ๋ณด์ž!

์•—... ํ•˜๊ธฐ๋„ ์ „์— โš ๏ธ ๋ฌธ์ œ ๋ฐœ์ƒ! ๋ฌธ์ œ ๋ฐœ์ƒ!


โš ๏ธ ๋ฌธ์ œ ๋ฐœ์ƒ!


๋ฌธ์ œ

์•„๋‹ˆ ์ด๊ฒŒ ๋ญ์•ผ.. ๋ถ„๋ช…ํžˆ prop์œผ๋กœ isOwner๋ฅผ Tweet ์ปดํฌ๋„ŒํŠธ์— ๋ณด๋‚ผ ๋•Œ tweet.creatorId === userObj.uid๊ฐ€ ์ฐธ์ธ ๊ฒฝ์šฐ์—๋งŒ ์ˆ˜์ •/์‚ญ์ œ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํŠผ์ด ๋œจ๋„๋ก ์„ค์ •ํ•ด ๋‘์—ˆ๋Š”๋ฐ ๋‹ค๋ฅธ ์œ ์ €๋กœ ๋กœ๊ทธ์ธํ•ด์„œ ๋“ค์–ด๊ฐ”๋Š”๋ฐ๋„ ์ˆ˜์ •/์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ด๋ ‡๊ฒŒ ๋˜ ๋‚˜์˜ ์‚ฝ์งˆ์€ ์‹œ์ž‘๋˜์—ˆ๋‹ค.

ํ•ด๊ฒฐ

๊ฒฐ๋ก ์ ์œผ๋กœ ๊ฐ„๋‹จํ•œ ์‹ค์ˆ˜์˜€๋‹ค. ์•Œ๊ณ ๋‚˜๋‹ˆ ๋„ˆ๋ฌด๋‚˜ ๋จธ์“ฑํƒ€๋“œ..

๐Ÿ“ src/components/Tweet.js

// โŒ
const Tweet = ({ tweetObj }, isOwner ) => { };

// โœ…
const Tweet = ({ tweetObj, isOwner } ) => { };

prop์„ ์ด์ƒํ•˜๊ฒŒ ๋ณด๋‚ด๊ณ  ์žˆ์—ˆ๋‹ค๋Š” ์‚ฌ์‹ค...ใ… ใ… 
์ด๋Ÿฐ๊ฑฐ ์‹ค์ˆ˜ํ•  ์ค„์€ ๋ชฐ๋ž๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฐ์˜ 2์‹œ๊ฐ„์€ ์‚ฝ์งˆํ•œ ๊ฒƒ ๊ฐ™๋‹ค..ใ…Ž...ใ…Žใ…Žใ…Ž..
์›ƒ๊ธด๋ฐ ์•ˆ ์›ƒ๊ฒจ...๐Ÿฅฒ


ํด๋ฆฌ๋‹ ์ฝ”๋“œ


Home.js ์™€ Auth.js์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ๋บ„ ์ˆ˜ ์žˆ๋Š” ์นœ๊ตฌ๋“ค์„ ๋”ฐ๋กœ ๋นผ์ฃผ์ž.

  • ํ™ˆ์— ์žˆ๋˜ ํŠธ์œ— ๋งŒ๋“œ๋Š” ํผ ๋ถ€๋ถ„์„ TweetFactory.js ์ปดํฌ๋„ŒํŠธ๋กœ ๋บ๋‹ค.
  • ์–ด์Šค์— ์žˆ๋˜ ๋กœ๊ทธ์ธ/๊ฐ€์ž… ํผ ๋ถ€๋ถ„์„ AuthForm.js ์ปดํฌ๋„ŒํŠธ๋กœ ๋บ๋‹ค.

ํ”„๋กญ ์•ˆ ๋น ์ง€๊ฒŒ ์ž˜ ๋ณด๋‚ด์ฃผ์ž! ๋‹คํ–‰ํžˆ๋„ ๋ฆฌ์•กํŠธ๊ฐ€ ์นœ์ ˆํ•˜๊ฒŒ ์ฝ”๋“œ์— ๋ญ ๋น ์กŒ๋Š”์ง€ ์•Œ๋ ค์ค€๋‹ค.

getMyTweets ํŽ‘์…˜ ์™„์„ฑํ•˜๊ธฐ


์•„ ์ €๋ฒˆ์— ํ”„๋กœํ•„์—์„œ ์‚ฌ์šฉ์ž ๋ณธ์ธ์ด ์ ์€ ํŠธ์œ—๋งŒ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ ๊ฐ€์ ธ์˜จ doc์„ ๊ทธ๋ƒฅ ์ฝ˜์†”๋กœ๊ทธ์—๋งŒ ์ฐ์–ด ๋‘๊ณ  ์žˆ๋Š” ์‹ค์ •์ด์—ˆ๋‹ค. ์‰… ๋งˆ๋ฌด๋ฆฌ๋„ ๋‹ค ๋˜์–ด๊ฐ€๋Š” ๋งˆ๋‹น์— ์ผ๋‹จ ํ™”๋ฉด์— ์ถœ๋ ฅ์ด๋‚˜ ์‹œ์ผœ๋ณด์ž ํ•˜๊ณ  home์—์„œ ํ–ˆ๋˜ ๊ฒƒ ์ฒ˜๋Ÿผ ํŠธ์œ—์„ ๊ฐ€์ ธ์™€์„œ map๋ฉ”์„œ๋“œ๋กœ ํŠธ์œ—์„ ํ•˜๋‚˜ ์”ฉ ๋‚˜์—ดํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค.

import Tweet from "components/Tweet";
import { authService, dbService } from "fbase";
import { updateProfile } from "firebase/auth";
import {
  collection,
  getDocs,
  onSnapshot,
  orderBy,
  query,
  where,
} from "firebase/firestore";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

//์ƒ๋žต

 const [tweets, setTweets] = useState([]);
  //๋‚ด ํŠธ์œ— ๊ฐ€์ ธ์˜ค๊ธฐ: map์œผ๋กœ
  useEffect(() => {
    //snapshot์€ ์ฟผ๋ฆฌ ๊ฐ™์€ ๊ฑด๋ฐ docs๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
    //tweets์€ ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ snapshot์—์„œ ๋‚˜์˜ค๋Š” ๊ฑฐ๋‹ค.
    //๋”ฐ๋ผ์„œ setTweets()์„
    const q = query(
      collection(dbService, "tweets"),
      where("creatorId", "==", userObj.uid),
      orderBy("createdAt", "desc")
    );
    const unsubscribe = onSnapshot(q, (snapshot) => {
      //๋ชจ๋“  docs๋Š” {} ์˜ค๋ธŒ์ ํŠธ ๋ฐ˜ํ™˜ํ•˜๋„๋ก
      //์•„์ด๋”” ๊ฐ€์ ธ์˜ค๊ณ , ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ ์ „์ฒด ๊ฐ€์ ธ์˜ค๊ธฐ
      const tweetArr = snapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
      //ํŠธ์œ—์–ด๋ ˆ์ด ํ™•์ธํ•ด๋ณด์ž. ์˜ค์ผ€์ด ์›ํ•˜๋Š”๋Œ€๋กœ ํฌ๋งท๋œ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค!
      //console.log(tweetArr);
      setTweets(tweetArr);
    });
    return () => {
      unsubscribe();
    };
  }, [userObj.uid]);

//์ƒ๋žต

return(
<>
    <div>
        {tweets.map((tweet) => (
          //Tweet์„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๊ณ  props์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.
          //tweetObj ๋งŒ๋“ค ๋•Œ ๊ฐ๊ฐ์˜ tweet์— ํ• ๋‹นํ•œ id ๊ฐ’์„ div์˜ key์— ๋„ฃ์–ด์ฃผ์ž
          <Tweet
            key={tweet.id}
            tweetObj={tweet}
            isOwner={tweet.creatorId === userObj.uid}
          />
        ))}
      </div>
  </>)

์ฐธ๊ณ : ๊ธฐ์กด์— ์ž‘์„ฑํ•ด ๋‘” getMyTweets ํŽ‘์…˜

๊ธฐ์กด์— ์ž‘์„ฑํ–ˆ๋˜ ํŽ‘์…˜์˜ ๊ฒฝ์šฐ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ’์„ getDocs()๋ฉ”์„œ๋“œ๋กœ ๊ฐ€์ ธ์˜ค๊ณ  ์žˆ๊ณ , ๊ทธ๊ฑธ forEach()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฟŒ๋ฆฌ๊ณ  ์žˆ์—ˆ๋‹ค.

 //๋‚ด Tweets ์–ป๋Š” function ์ƒ์„ฑ
  const getMyTweets = async () => {
    //ํŠธ์œ— ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    //dbService์˜ ์ปฌ๋ ‰์…˜ ์ค‘ "tweets" Docs ์ค‘์—์„œ, userObj์˜ uid์™€ ๋™์ผํ•œ creatorID๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ๋ฌธ์„œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ฟผ๋ฆฌ(์š”์ฒญ) ์ƒ์„ฑ
    //ํŠธ์œ—ํ•œ ์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌํ•˜๊ธฐ
    const q = query(
      collection(dbService, "tweets"),
      where("creatorId", "==", userObj.uid),
      orderBy("createdAt", "desc")
    );
    //getDocs()๋ฉ”์„œ๋“œ๋กœ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ
    const querySnapshot = await getDocs(q);
    querySnapshot.forEach((doc) => {
      //โœ… ์ฝ˜์†”์— ์ฐ๊ธฐ
      console.log(doc.id, "=>", doc.data());
    });
  };
  //๋‚ด Tweets ์–ป๋Š” function ํ˜ธ์ถœ
  useEffect(() => {
    getMyTweets();
  }, []);

forEach() vs map()

๋‘˜๋‹ค ๋ฐฐ์—ด(array)์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ณตํ†ต์ ์ด ์žˆ๋Š”๋ฐ,

  • forEach(): ๋ฐฐ์—ด ์š”์†Œ๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ ์ฃผ์–ด์ง„ ํ•จ์ˆ˜(์ฝœ๋ฐฑ)์„ ์‹คํ–‰ํ•จ, ์ฆ‰ ๊ธฐ์กด ๋ฐฐ์—ด์„ ๋ณ€๊ฒฝ
    ๊ทธ๋ฆฌ๊ณ 
  • map(): ๋ฐฐ์—ด ๋‚ด์˜ ๋ชจ๋“  ์š”์†Œ ๊ฐ๊ฐ์— ๋Œ€ํ•ด ์ฃผ์–ด์ง„ ํ•จ์ˆ˜(์ฝœ๋ฐฑ)์„ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ชจ์•„์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•จ
profile
Always have hope๐Ÿ€ & constant passion๐Ÿ”ฅ

0๊ฐœ์˜ ๋Œ“๊ธ€