์ค๋ ์๋ฃํ ๋ชฉ๋ก
1. ์ด ํธ์ ์ด ์ฌ๋ ๋๊ตฌ์ฌ
2. ์ค์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ํธ์ ๋ชฉ๋ก ํ๋ฉด์ ๋ํ๋ด๊ธฐ
3. ํ๋ฐ ์ฝ๋ ์์
์ ์ํ ์ปดํฌ๋ํธ ๋ถ๋ฆฌ ๋ฐ ํธ์ ์ญ์ ๋ฐ ์์ ๊ถํ ๋ถ์ฌ
4. ํธ์ ์ญ์ ๋ฐ ์์ ๊ธฐ๋ฅ ~ing
const [userObj, setUserObj] = useState(null);
// ๋ก๊ทธ์ธ ์ ๋ณด๊ด๋ฆฌ๋ฅผ ์ํ useState
useEffect(() => {
auth.onAuthStateChanged((user) =>{
if(user){
setIsLoggedIn(true);
setUserObj(user);
}else{
setIsLoggedIn(false)
}
setInit(true);
});
}, []);
return (
<>
{init ? <AppRouter isLoggedIn = {isLoggedIn} userObj={userObj} /> : "Initialzizing.."}
{/* userObj๋ฅผ AppRouter์ ์ด์ฉํ์ฌ ๋ณด๋ */}
<footer>© {new Date().getFullYear()} Nwitter</footer>
</>
)
ํธ์์ ์์ด๋๋ฅผ ์ ์ฅํ์ง ์์ผ๋ฉด ๋๊ฐ ์ด๋ค ํธ์์ ์ผ๋์ง ์ ์ ์๊ธฐ ๋๋ฌธ์
๋ก๊ทธ์ธ ์ ๋ณด๊ด๋ฆฌ๋ฅผ ์ํด useState๋ฅผ ํ์ฉํ์ฌ userObjํจ์๋ฅผ ๋ง๋ค์๋ค. ๊ทธ๋ฆฌ๊ณ if๋ฌธ์ ์ด์ฉํ์ฌ
๋ง์ฝ user๋ผ๋ฉด userObjํจ์๋ฅผ ์ด์ฉํ์ฌ id๋ฅผ ๋ด๋ณด๋ด๊ฒ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ด๊ฐ app.js์์ ๋ง๋ userObjํจ์๋ฅผ ๋ค๋ฅธ ๊ณณ์์๋ ์ฐ๊ธฐ ์ํด
AppRouter์ ํตํด ๋ณด๋๋ค.
๋ณด๋ฉด creatorID๊ฐ ์ข ๋ง์ด ์น ํด์ ธ์ ์๋ณด์ด์ง๋ง ์์ด๋๊ฐ ๋์ผํ๋ค.
์ )
const [nweets, setNweets] = useState([]);
// ํธ์๋ค์ ์ํ๋ก ๋ฐ์์ ๋ณด๊ดํด์ผํ๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด๋ก usestate ์์ฑ
const getNweets = async ()=> {
const q = query(collection(dbService,"nweets"));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
const nweetObj = { //nweetObj => ํธ์ ๋ด์ฉ
...doc.data(),
id:doc.id,
}
setNweets(prev => [nweetObj,...prev]);
});
ํ)
const [nweets, setNweets] = useState([]);
// ํธ์๋ค์ ์ํ๋ก ๋ฐ์์ ๋ณด๊ดํด์ผํ๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด๋ก usestate ์์ฑ
useEffect(() => {
onSnapshot(
query(collection(dbService, "nweets"), orderBy("createdAt", "desc")),
(snapshot) => {
const nweetArray = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setNweets(nweetArray);
}
);
}, []);
์ค์๊ฐ์ผ๋ก ํธ์ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด์ ๋จผ์ ๊ธฐ์กด์ ์ฐ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์์์๋ค..ใ
ใ
๊ธฐ์กด์ ์ฐ๋ getNweets๋ฅผ ์์ ๊ณ ํ์ด์ด๋ฒ ์ด์ค์ onSnapshot ํจ์๋ฅผ ์ด์ฉํ๋ค.
์ด ํจ์๋ ์ ๋ง ๋๋ฌด๋๋ฌด ์ ์ฉํ๋๋ฐ ์ด ํจ์ ํ๋๋ก ์ค์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ์ ์์๋ค.
์์ธํ ์ค๋ช
ํ์๋ฉด, onSnapshotํจ์๋ ๋ชจ๋ ์ค๋
์ท์ ๋ฐํํ๋ค.
๊ทธ๋ ๊ฒ ๋ฐ์ snapshot์์ ์ํ๋ ๋ฐ์ดํฐ๋ง ๋ฝ๊ธฐ ์ํด์ mapํจ์๋ฅผ ์ฌ์ฉํ๋ค.
์ ์ ์๋ ์ฝ๋๋ forEachํจ์๋ฅผ ์ด์ฉํ์ฌ ์ํํ ๋๋ง๋ค setNweetsํจ์๋ฅผ ์คํํ์ด์ผ ํ์ง๋ง
mapํจ์๋ฅผ ์ด์ฉํ์ฌ ์ํํ๋ฉด์ ๋ฐ์ ๋ฐฐ์ด์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ setNweetํจ์์ ๋จ 1๋ฒ๋ง ๋ฐฐ์ด์ ์ ๋ฌํ๋ฉด ๋์ ํจ์ฌ ํจ์จ์ ์ด๋ค!
์ ์ ์ฝ๋๋ฅผ ์ ์ด๋๊ฐ ์๋ก home.js์ ์ปดํฌ๋ํธ์ ์ถ๊ฐํด์ผํ๋ค. ๊ทธ๋ ๊ฒ ๋๋ฉด
์ฝ๋์ ๋ฉ์น๋ ์ปค์ง๊ณ ๋ณด๊ธฐ์๋ ์ ์ข๊ธฐ ๋๋ฌธ์ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฆฌํ๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Nweet.js๋ก ๋ณ๋๋ก ํธ์์ฉ ์ปดํฌ๋ํธ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ ํ์ผ์ ๋ง๋ค์๋ค.
import React from "react";
const Nweet = ({nweetObj, isOwner}) =>{
}
return (
<div>
<h4>{nweetObj.nweet}</h4>
{isOwner && (
<>
<button>Delete tweet</button>
<button>Edit Nweet</button>
</>
)}
</div>
);
};
export default Nweet;
๊ธฐ์กด์ home์ ์ปดํฌ๋ํธ์ ๋ค๋ฅธ ๊ฒ์ home ์ปดํฌ๋ํธ์ map ํจ์์์ ๋ฐํํ๋ nweetObj ๋ฐฐ์ด์
ํ๋กญ์ค๋ก ๋ฐ๋๋ค๋ ๊ฒ๋ง ๋ค๋ฅด๋ค.
Nweet ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ์ญ์ ์ ์์ ์ ์ํ ๋ฒํผ์ ๋ง๋ค์๋ค.
import Nweet from "components/Nweet";
<div>
{nweets.map((nweet) => (
// map ํจ์๋ฅผ ์ด์ฉํ์ฌ nweets ๋ฐฐ์ด์ ์ํํ๋ฉด์ jsx๋ฅผ ๋ฐํํ๊ฒ ๋ง๋ค์ด์ ํธ์ ๋ฐฐ์ด๋ค์ ์น์ ๋ํ๋.
<Nweet
key={nweet.id}
nweetObj={nweet}
isOwner={nweet.creatorId === userObj.uid}
// isOwner nweet.creatorId === userObj.uid๊ฐ ๊ฐ์์ผ ๊ถํ์ ์ค ์ ์๊ฒ ์ค์ .
/>
))}
</div>
์ด์ home.js์์ ์์์ ๋ง๋ nweet์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด import ํ๊ณ
nweet ์ปดํฌ๋ํธ๋ฅผ ์
๋ ฅํ๋ค.
๊ทธ๋ฆฌ๊ณ ์์ ๋ฐ ์ญ์ ๊ถํ์ ์ ํธ์์ ์ด ์ฌ์ฉ์๋ง ํ ์ ์๊ฒ ํ๊ธฐ ์ํด์ ์์๋ ์์ง๋ง ์์ธํ ์ค๋ช
ํ๋ฉด,
home.js์๋
isOwner={nweet.creatorId === userObj.uid}
์ถ๊ฐํ๊ณ Nweet.js์์ Nweet ์ปดํฌ๋ํธ์์ isOwner๋ผ๋ ํ๋กญ์ค๋ ๋ฐ๊ฒ ํ๋ค.
ํธ์ ์์ฑ์์ ์์ด๋๋ก ๋ดค์ ๋
๋ค๋ฅธ ์ฌ์ฉ์๋ก ๋ดค์ ๋
ํธ์ ์ญ์ ๊ธฐ๋ฅ์ ๋ง๋ค๊ธฐ ์ํด์ ํจ์ํ๋๋ง ํ์ฌ ๋ง๋ค์ด๋์ ์ํ๋ค ^^
nweet.js์ nweet ์ปดํฌ๋ํธ ์์ ์ถ๊ฐํด์คฌ๋ค.
const onDeleteClick = () => {
const ok = window.confirm("Are you sure you want to delete this tweet?");
if(ok){
//delete tweet
}
์ด๊ฑฐ๋ ๋ญ.. ์ฐฝ์ผ๋ก ์ง์ง ์ญ์ ํ ๊ฑฐ๋๊ณ ๋จ๊ฒ๋ง ์ผ๋จ ํด๋จ๋ค
nweet.js
import React from "react";
const Nweet = ({nweetObj, isOwner}) =>{
const onDeleteClick = () => {
const ok = window.confirm("Are you sure you want to delete this tweet?");
if(ok){
//delete tweet
}
}
return (
<div>
<h4>{nweetObj.nweet}</h4>
{isOwner && (
<>
<button>Delete tweet</button>
<button>Edit Nweet</button>
</>
)}
</div>
);
};
export default Nweet;
home.js
import { dbService } from 'fbase';
import React,{useState, useEffect} from "react";
import {addDoc, collection,query, onSnapshot,orderBy} from "firebase/firestore";
import Nweet from "components/Nweet"
const Home = ({userObj}) => {
const [nweet, setNweet] = useState("");
const [nweets, setNweets] = useState([]); // ํธ์๋ค์ ์ํ๋ก ๋ฐ์์ ๋ณด๊ดํด์ผํ๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด๋ก usestate ์์ฑ
useEffect(() => {
onSnapshot( // OnSnapshot ํจ์๋ฅผ ์ด์ฉํ์ฌ ๋ชจ๋ ์ค๋
์ท์ ๋ฐํํจ.
query(collection(dbService, "nweets"), orderBy("createdAt", "desc")),
(snapshot) => {
const nweetArray = snapshot.docs.map((doc) => ({
id: doc.id, // map ํจ์๋ฅผ ์ด์ฉํ์ฌ ์ค๋
์ท์์ ์ํ๋ ๋ฐ์ดํฐ๋ง ๋ฝ์์ ๋ฐฐ์ดํ ์ํจ ํ ํ๋ฉด์ ๋ํ๋.
...doc.data(), // ์ ์ ์ฌ์ฉํ๋ Foreachํจ์๋ ๋งค ์ํ๋ง๋ค setNweets๋ฅผ ์ฌ์ฉํด์ผํ์ง๋ง, mapํจ์๋ ์ํํ๋ฉด์ ๋ง๋ ๋ฐฐ์ด์ ๋ฐํํ๋ฏ๋ก
// ๋ฐํํ ๋ฐฐ์ด์ 1๋ฒ๋ง setNweetํจ์์ ์ ๋ฌํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ํจ์ฌ ํจ์จ์ ์ด๋ค.
}));
setNweets(nweetArray);
}
);
}, []);
const onSubmit = async (e) => {
try{
e.preventDefault();
const docRef = await addDoc(collection(dbService, "nweets"),
{
nweet,
createdAt: Date.now(),
creatorId : userObj.uid, // db์ ์ ์ ์์ด๋ ์ถ๊ฐ
}); // ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฑ
console.log("Document Written with Id:", docRef.id);
}catch(error){
console.log("Error adding document", error)
}
setNweet("");
};
const onChange = (event) =>{
const {target : {value},
}= event;
setNweet(value);
};
console.log(nweets);
return (
<>
<div>
<form onSubmit={onSubmit}>
<input value={nweet} onChange={onChange} type = "text" placeholder ="what's on your mind" maxLength={120} />
<input type="submit" value="nweet"/>
</form>
<div>
{nweets.map((nweet) => (
// map ํจ์๋ฅผ ์ด์ฉํ์ฌ nweets ๋ฐฐ์ด์ ์ํํ๋ฉด์ jsx๋ฅผ ๋ฐํํ๊ฒ ๋ง๋ค์ด์ ํธ์ ๋ฐฐ์ด๋ค์ ์น์ ๋ํ๋.
<Nweet
key={nweet.id}
nweetObj={nweet}
isOwner={nweet.creatorId === userObj.uid}
// isOwner nweet.creatorId === userObj.uid๊ฐ ๊ฐ์์ผ ๊ถํ์ ์ค ์ ์๊ฒ ์ค์ .
/>
))}
</div>
</div>
</>
);
};
export default Home;
App.js
import AppRouter from 'components/Router';
import {useState, useEffect} from "react";
import { auth } from "fbase";
function App() {
const [init, setInit] = useState(false)
const [isLoggedIn, setIsLoggedIn] = useState(auth.currentUser)
const [userObj, setUserObj] = useState(null); // ๋ก๊ทธ์ธ ์ ๋ณด๊ด๋ฆฌ๋ฅผ ์ํ useState
useEffect(() => {
auth.onAuthStateChanged((user) =>{
if(user){
setIsLoggedIn(true);
setUserObj(user);
}else{
setIsLoggedIn(false)
}
setInit(true);
});
}, []);
return (
<>
{init ? <AppRouter isLoggedIn = {isLoggedIn} userObj={userObj} /> : "Initialzizing.."}
{/* userObj๋ฅผ AppRouter์ ์ด์ฉํ์ฌ ๋ณด๋ */}
<footer>© {new Date().getFullYear()} Nwitter</footer>
</>
)
}
export default App;
์๋ฐํ๊ณ ์ ๊ณต ์ค๊ฐ๊ณ ์ฌ ๋์ฒด ๋ณด๊ณ ์ ์ฐ๊ณ ์ด๋ํ๋๋ผ ์น ๊ณต๋ถ๋ฅผ ๋ง์ด ๋ชปํ๋ค..
๊ทธ๋๋ ์งฌ๋ด์ ๊ณต๋ถํ๊ณ ๋ธ๋ก๊ทธ๋ ์ด ๊ฑฐ์ ์์๋ฅผ ๋์..๐ฅฒ
์ด๋๋ณด๋จ ์น์ด ๋จผ์ ์๋๊ฐ์ ? ใ ใ ์์ดํ๋ค์