๐ Twitter Clone: Getting the Tweets(cRud)
CRUD with firebase: โ
Read(์ฝ๊ธฐ)-Getting the Tweets
ํธ์์ ์์ฑํ์ฌ db์ create ํ๋ ๊ฒ์ ์๋ฃํ์ผ๋ ์ด์ ํ์ด์ด์คํ ์ดdb์์ ์์ฑํ ํธ์์ ๊ฐ์ ธ์ read! ์ฝ์ด๋ณด์!
1. ์ธํ
firebase/firestore
๋ก ๋ถํฐquery
์getDocs
๋ฅผ import ํ๋ค.
import {
collection,
addDoc,
serverTimestamp,
//๊ฐ์ ธ์ค๊ธฐ
query,
getDocs,
} from "firebase/firestore";
- Home ์ปดํฌ๋ํธ์
useState()
๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑํ ํธ์์ ๊ฐ์ ธ์ค๋ ์คํ ์ดํธ๋ฅผ ๋ง๋ ๋ค.
์ด๋ ๊ธฐ๋ณธ ๊ฐ์ ๋น๋ฐฐ์ด(array)
๋ก ์ค์ ํ์ฌ ์์ฑํ ํธ์ ๋ฐ์ดํฐ๋ค์ด ๋ฐฐ์ด์ ๋ค์ด๊ฐ ์ ์๊ฒ ํ์.
//๐ฅ์์ฑํ ํธ์ ๊ฐ์ ธ์ค๊ธฐ: ๊ธฐ๋ณธ ๊ฐ์ ๋น ๋ฐฐ์ด
const [tweets, setTweets] = useState([]);
- Home ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋๋ฉด
useEffect(fn, []);
๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ ๋ด์ฉ๋ค์ ๊ฐ์ ธ์ค์.
- ๊ทธ๋ฌ๊ธฐ ์ํด ํธ์ ๋ด์ฉ์ ๊ฐ์ ธ์ค๋ ํจ์
getTweets
์ ๋ง๋ค๊ณ ์ด ํจ์๋ฅผ ํธ์ถํ์.- ์ด๋
async
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๊ฐ๋ณ ํจ์๋ก ๋ฐ์ผ๋ก ๋นผ์ ๋ง๋ ํ, useEffect()์์ ํธ์ถํ๊ธฐ ์ํด์์ด๋ค.
- ์ด๋
useEffect(() => {
getTweets();
}, []);
์ฉ์ด ์๊ณ ๋์ด๊ฐ๊ธฐ
- ๋ง์ดํธ(mount)
: ํ์ผ์์คํ ๊ตฌ์กฐ ๋ด์ ์๋ ์ผ๋ จ์ ํ์ผ๋ค์ ์ฌ์ฉ์๋ ์ฌ์ฉ์ ๊ทธ๋ฃน๋ค์ด ์ด์ฉํ ์ ์๋๋ก ๋ง๋๋ ๊ฒ
2. ํธ์ ๋ด์ฉ์ ๊ฐ์ ธ์ฌ getTweets ํจ์์ ๋ด์ฉ์ ์ฑ์๋ณด์.
์ฌ๊ธฐ์ ์ฌ์ฉํ firestore์ ๋ฉ์๋
getDocs()
๋ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ QuerySnapshot์ผ๋ก ๋ฐํํ๋ค.
- getDocs๋ promise๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์
async
,await
์ ์ฌ์ฉํ์.
QuerySnapshot ํด๋์ค
- QuerySnapshot์๋ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ด๋ 0๊ฐ ์ด์์ DocumentSnapshot ๊ฐ์ฒด๊ฐ ํฌํจ๋์ด ์๋ค.
- ๋คํ๋จผํธ๋, docs ์์ฑ์ ํตํด
๋ฐฐ์ด
๋ก ์ก์ธ์คํ๊ฑฐ๋ /forEach ๋ฉ์๋
๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ฑฐํ ์ ์๋ค.- ๋ฌธ์์ ์๋ empty ๋ฐ size ์์ฑ์ ํตํด ๊ฒฐ์ ํ ์ ์๋ค.
const getTweets = async () => {
/*1. DB์์ ์ปฌ๋ ์
๊ฐ์ ธ์ค๊ธฐ
dbService์ ์๋ tweets ์ปฌ๋ ์
์ ๊ฐ์ ธ์ค๋ ์ฟผ๋ฆฌ ๋ง๋ค๊ธฐ*/
const q = query(collection(dbService, "tweets"));
/*2. ์ปฌ๋ ์
์ ๋คํ๋จผํธ ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ
- ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ QuerySnapshot์ผ๋ก ๋ฐํํ๋ฉด tweets ์ปฌ๋ ์
์ document๋ค์ ์ป๋๋ค.
- ๋ฐ๋ผ์ querySnapshot์ tweets ์ปฌ๋ ์
์ document๋ค์ ๋ชจ์๋์ ๋ฐฐ์ด์ด๋ค.*/
const querySnapshot = await getDocs(q);
//3. ๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๋์ด
querySnapshot.forEach((document) => {
/*๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๋์ดํ ๋ {data, id} ์ค๋ธ์ ํธ ํํ๋ก ๋์ดํ์.
- document์ data๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด data() ๋ฉ์๋ ์ฌ์ฉ
- ํธ์ ํ๋์ฉ ๋์ด ํ ๋ ์ธ key ๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ id ํ ๋น*/
const tweetObj = {
...document.data(),
id: document.id,
};
//console.log(tweetObj);
//- setTweets() ๋ชจ๋ํ์ด์ด๋ก ์ด์ tweets(prev)์ ๋ํด, ์๋ก์ด ๋ฐฐ์ด(์๋ก ์์ฑํ ํธ์๊ณผ, ...๊ทธ ์ด์ ๊ฒ๋ค)์ ๋ฆฌํดํด์ฃผ์.
setTweets((prev) => [tweetObj, ...prev]);
});
};
-
๋จผ์ ํ์ด์ด์คํ ์ด์์ ์ฌ์ฉํ
์ปฌ๋ ์
์ ๊ฐ์ ธ์์ผ ํ๋ค.
query()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ,dbService
์ ์๋tweets ์ปฌ๋ ์
์ ๋ํ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค์. -
์ปฌ๋ ์ ์ ๊ฐ์ ธ์์ผ๋ tweets ์ปฌ๋ ์ ์
document๋ค
์ ๊ฐ์ ธ์ค์.- ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ QuerySnapshot์ผ๋ก ๋ฐํํ๋
getDocs()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. - ์ด ๋ฉ์๋์ ๋ฐฉ๊ธ ๋ง๋ ์ฟผ๋ฆฌ(
q
)๋ฅผ ๋ณด๋ด๊ณ , ์ด ๊ฐ์querySnapshot
๋ณ์๋ก ํ ๋นํ์. getDocs()
์ ํธ์ถํ ๋๋await
์ ์ฌ์ฉํ์ฌ ๋๊ธฐ์ฒ๋ฆฌ ํด์ฃผ์.
- ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ QuerySnapshot์ผ๋ก ๋ฐํํ๋
-
๋ชจ๋ ๋คํ๋จผํธ๋ฅผ ๊ฐ์ง ๋ฐฐ์ด์ธ querySnapshot์์ ๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๋์ดํ๊ธฐ ์ํด์๋ forEach๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ๋ค์๊ณผ ๊ฐ์ ์ค๋ธ์ ํธ ํํ๋ก ๋์ด๋๊ฒ ํ์.
{๋คํ๋จผํธ์ data, id}
- ๊ฐ๊ฐ์ ๋คํ๋จผํธ์ data๋
data() ๋ฉ์๋
๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ ธ์ค๋ฉด ๋๋ค. - ๋คํ๋จผํธ์ id๋ฅผ ํ ๋นํ์.
- ๊ทธ๋ฅ data๋ง ๊ฐ์ ธ์ฌ๊ฑฐ๋ฉด ์ค๋ธ์ ํธ ํํ๋ก ๋ง๋ค์ง ์์๋ ๋๋ค. ๊ทธ๋ฐ๋ฐ ๋๋น์์ ๋ฐ์์จ ๋คํ๋จผํธ์ธ ํธ์ ๋ด์ฉ์ ํ๊ทธ๋ก ์์ฑํด์ ๋์ดํ ๋, ํธ์ ๋ด์ฉ ๊ฐ๊ฐ์ key๊ฐ์ ํ ๋นํด์ผ ํ๊ธฐ ๋๋ฌธ์ id๋ฅผ ํ ๋นํด ์คฌ๋ค. ๋ฐ๋ผ์ ์ค๋ธ์ ํธ ํํ๋ก ์์ฑํ๊ฒ ๋์๋จ ์๋ฆฌ.
- ๊ฒฐ๋ก ์ ์ผ๋ก forEach ์จ์ ๋ชจ๋ ๋คํ๋จผํธ๋ฅผ ๋์ดํ๋ฉด ์ด๋ฐ ๋ชจ์์๋ค.
console.log(tweetObj);
๋ฅผ ํด๋ณด๋ฉด ์ปฌ๋ ์ ์ ๋ค์ด ์๋ ๋คํ๋จผํธ๋ค์ด ๊ฐ๊ฐ์ ์ค๋ธ์ ํธ๋ก ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.(ํธ์ ๋ด์ฉ์ ์ฐ๋ฃจํฉ์๋น..^^~)
- ๊ทธ๋ฌ๊ณ ๋์
setTweets()
๋ชจ๋ํ์ด์ด๋ก state๋ฅผ ์ ๋ฐ์ดํธ ํด์ฃผ์. ๊ทธ๋์ผ ๋ฐฉ๊ธ ์ด ํธ์๋ tweets state์ ๋ค์ด๊ฐ๋ค.- ์ด ๋, ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ ๊ฐ์ ์ ๋ฐ์ดํธ ํ์.
- ES6์ ์คํ๋ ๋ ์ฐ์ฐ์
...
๋ฅผ ์ฌ์ฉํ์ฌ, ์ด์ tweets
(prev)์ ๋ํด, ์๋ก์ด ๋ฐฐ์ด(์๋ก ์์ฑํ ํธ์๊ณผ, ...๊ทธ ์ด์ ๊ฒ๋ค)์ ๋ฆฌํดํด์ฃผ์.
- ๊ฐ๊ฐ์ ๋คํ๋จผํธ์ data๋
3. ํธ์ ๋ด์ฉ ๋์ดํ๊ธฐ
- ํธ์ ๋ด์ฉ์ด ๋
tweets
state๋๋ฐฐ์ด
์ด๊ธฐ ๋๋ฌธ์, ๋ฐฐ์ด์ item์ ๋์ดํ๊ธฐ ์ํดmap()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์.<div> {tweets.map((tweet) => ( //tweetObj ๋ง๋ค ๋ ๊ฐ๊ฐ์ tweet์ ํ ๋นํ id ๊ฐ์ div์ key์ ๋ฃ์ด์ฃผ์ <div key={tweet.id}> <h4>{tweet.tweet}</h4> </div> ))} </div>
์ ์ฒด ์ฝ๋
๐ Home.js
import React, { useEffect, useState } from "react";
import { dbService } from "fbase";
import {
collection,
addDoc,
serverTimestamp,
query,
getDocs,
} from "firebase/firestore";
const Home = () => {
//ํ์์ ํธ์ ๋ด์ฉ ์์ฑํ๋ ํผ
const [tweet, setTweet] = useState("");
//0. ์์ฑํ ํธ์ ๊ฐ์ ธ์ค๊ธฐ: ๊ธฐ๋ณธ ๊ฐ์ ๋น ๋ฐฐ์ด
const [tweets, setTweets] = useState([]);
const getTweets = async () => {
/*1. DB์์ ์ปฌ๋ ์
๊ฐ์ ธ์ค๊ธฐ
dbService์ ์๋ tweets ์ปฌ๋ ์
์ ๊ฐ์ ธ์ค๋ ์ฟผ๋ฆฌ ๋ง๋ค๊ธฐ*/
const q = query(collection(dbService, "tweets"));
/*2. ์ปฌ๋ ์
์ ๋คํ๋จผํธ ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ
- ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ QuerySnapshot์ผ๋ก ๋ฐํํ๋ฉด tweets ์ปฌ๋ ์
์ document๋ค์ ์ป๋๋ค.
- ๋ฐ๋ผ์ querySnapshot์ tweets ์ปฌ๋ ์
์ document๋ค์ ๋ชจ์๋์ ๋ฐฐ์ด์ด๋ค.*/
const querySnapshot = await getDocs(q);
//3. ๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๋์ด
querySnapshot.forEach((document) => {
/*๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๋์ดํ ๋ {data, id} ์ค๋ธ์ ํธ ํํ๋ก ๋์ดํ์.
- document์ data๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด data() ๋ฉ์๋ ์ฌ์ฉ
- ํธ์ ํ๋์ฉ ๋์ด ํ ๋ ์ธ key ๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ id ํ ๋น*/
const tweetObj = {
...document.data(),
id: document.id,
};
//- setTweets() ๋ชจ๋ํ์ด์ด๋ก ์ด์ tweets(prev)์ ๋ํด, ์๋ก์ด ๋ฐฐ์ด(์๋ก ์์ฑํ ํธ์๊ณผ, ...๊ทธ ์ด์ ๊ฒ๋ค)์ ๋ฆฌํดํด์ฃผ์.
setTweets((prev) => [tweetObj, ...prev]);
});
};
//4. ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋๋ฉด useEffect()์ฌ์ฉ
useEffect(() => {
getTweets();
}, []);
const onSubmit = async (event) => {
event.preventDefault();
//ํธ์ํ๊ธฐ ๋๋ฅด๋ฉด ์๋ก์ด document ์์ฑํ๊ธฐ
try {
const docRef = await addDoc(collection(dbService, "tweets"), {
tweet, // tweet(๋คํ๋จผํธ์ key): tweet(value๋ก tweet state ๊ฐ)
createdAt: serverTimestamp(), //Date.now(),๋ก ํด๋ ๋์ง๋ง ์ด์ ์๋๊ฑฐ ํจ ์จ๋ณด์(ํ์์กด ๋๋ถ์3 = ์์ธ๋ก ์ค์ ๋์ด ์์)
});
console.log("Document written with ID: ", docRef.id);
} catch (error) {
console.error("Error adding document: ", error);
}
//state ๋น์์ form ๋น์ฐ๊ธฐ
setTweet("");
};
const onChange = (event) => {
const {
target: { value },
} = event;
setTweet(value);
//console.log(tweet);
};
return (
<>
<div>
<form onSubmit={onSubmit}>
<input
type="text"
placeholder="๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์?"
maxLength={120}
value={tweet}
onChange={onChange}
/>
<input type="submit" value="ํธ์ํ๊ธฐ" />
</form>
</div>
{/*DB์์ ๊ฐ์ ธ์จ ํธ์ํฐ ๋์ด*/}
<div>
{tweets.map((tweet) => (
//tweetObj ๋ง๋ค ๋ ๊ฐ๊ฐ์ tweet์ ํ ๋นํ id ๊ฐ์ div์ key์ ๋ฃ์ด์ฃผ์
<div key={tweet.id}>
<h4>{tweet.tweet}</h4>
</div>
))}
</div>
</>
);
};
export default Home;
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ Twitter Clone: Getting the Tweets(cRud)), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค
https://velog.io/@summereuna/Twitter-Clone-Getting-the-Tweets-cRud
์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์
๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
import React, { useEffect, useState } from "react";
import { dbService } from "fbase";
import {
collection,
addDoc,
serverTimestamp,
query,
getDocs,
} from "firebase/firestore";
const Home = () => {
//ํ์์ ํธ์ ๋ด์ฉ ์์ฑํ๋ ํผ
const [tweet, setTweet] = useState("");
//0. ์์ฑํ ํธ์ ๊ฐ์ ธ์ค๊ธฐ: ๊ธฐ๋ณธ ๊ฐ์ ๋น ๋ฐฐ์ด
const [tweets, setTweets] = useState([]);
const getTweets = async () => {
/*1. DB์์ ์ปฌ๋ ์
๊ฐ์ ธ์ค๊ธฐ
dbService์ ์๋ tweets ์ปฌ๋ ์
์ ๊ฐ์ ธ์ค๋ ์ฟผ๋ฆฌ ๋ง๋ค๊ธฐ*/
const q = query(collection(dbService, "tweets"));
/*2. ์ปฌ๋ ์
์ ๋คํ๋จผํธ ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ
- ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ QuerySnapshot์ผ๋ก ๋ฐํํ๋ฉด tweets ์ปฌ๋ ์
์ document๋ค์ ์ป๋๋ค.
- ๋ฐ๋ผ์ querySnapshot์ tweets ์ปฌ๋ ์
์ document๋ค์ ๋ชจ์๋์ ๋ฐฐ์ด์ด๋ค.*/
const querySnapshot = await getDocs(q);
//3. ๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๋์ด
querySnapshot.forEach((document) => {
/*๊ฐ๊ฐ์ ๋คํ๋จผํธ๋ฅผ ๋์ดํ ๋ {data, id} ์ค๋ธ์ ํธ ํํ๋ก ๋์ดํ์.
- document์ data๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด data() ๋ฉ์๋ ์ฌ์ฉ
- ํธ์ ํ๋์ฉ ๋์ด ํ ๋ ์ธ key ๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ id ํ ๋น*/
const tweetObj = {
...document.data(),
id: document.id,
};
//- setTweets() ๋ชจ๋ํ์ด์ด๋ก ์ด์ tweets(prev)์ ๋ํด, ์๋ก์ด ๋ฐฐ์ด(์๋ก ์์ฑํ ํธ์๊ณผ, ...๊ทธ ์ด์ ๊ฒ๋ค)์ ๋ฆฌํดํด์ฃผ์.
setTweets((prev) => [tweetObj, ...prev]);
});
};
//4. ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋๋ฉด useEffect()์ฌ์ฉ
useEffect(() => {
getTweets();
}, []);
const onSubmit = async (event) => {
event.preventDefault();
//ํธ์ํ๊ธฐ ๋๋ฅด๋ฉด ์๋ก์ด document ์์ฑํ๊ธฐ
try {
const docRef = await addDoc(collection(dbService, "tweets"), {
tweet, // tweet(๋คํ๋จผํธ์ key): tweet(value๋ก tweet state ๊ฐ)
createdAt: serverTimestamp(), //Date.now(),๋ก ํด๋ ๋์ง๋ง ์ด์ ์๋๊ฑฐ ํจ ์จ๋ณด์(ํ์์กด ๋๋ถ์3 = ์์ธ๋ก ์ค์ ๋์ด ์์)
});
console.log("Document written with ID: ", docRef.id);
} catch (error) {
console.error("Error adding document: ", error);
}
//state ๋น์์ form ๋น์ฐ๊ธฐ
setTweet("");
};
const onChange = (event) => {
const {
target: { value },
} = event;
setTweet(value);
//console.log(tweet);
};
return (
<>
<div>
<form onSubmit={onSubmit}>
<input
type="text"
placeholder="๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์?"
maxLength={120}
value={tweet}
onChange={onChange}
/>
<input type="submit" value="ํธ์ํ๊ธฐ" />
</form>
</div>
{/*DB์์ ๊ฐ์ ธ์จ ํธ์ํฐ ๋์ด*/}
<div>
{tweets.map((tweet) => (
//tweetObj ๋ง๋ค ๋ ๊ฐ๊ฐ์ tweet์ ํ ๋นํ id ๊ฐ์ div์ key์ ๋ฃ์ด์ฃผ์
<div key={tweet.id}>
<h4>{tweet.tweet}</h4>
</div>
))}
</div>
</>
);
};
export default Home;
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ Twitter Clone: Getting the Tweets(cRud)), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@summereuna/Twitter-Clone-Getting-the-Tweets-cRud์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค