트위터 클론 코딩 #3 Nweeting
글 작성자: 택시 운전사
반응형
노마드 코더의 트위터 클론 코딩 강의를 듣고 정리한 강의노트입니다.
3 NWEETING
3.0 Form and Database Setup / 양식과 데이터베이스 설정
Firebase > Firestore Database
3.1 Nweeting! / 느위팅!
Firebase의 Cloude Database(Firestore Database)는 NoSQL database이기 때문에 유연하고 사용하기 쉽다. NoSQL database에는 다음과 같은 분류로 나뉜다.
- Collection : 폴더와 같은 역할, 한 데이터베이스에는 여러개의 Collection이 존재할 수 있다.
- Document : 폴더 안에 있는 문서와 같은 역할, 한 Collection에는 여러 개의 Document가 존재할 수 있다.
결론적으로 다음과 같은 포함관계를 갖게 된다.
Document ⊂ Collection ⊂ Database
Firebase v9.0으로 바뀌면서 firebaseConfig의 값이 달라졌다. 혹시 오류가 생긴다면 .env의 값이 현재 firebaseConfig에서 원하는 값과 같은 지 확인해보자.
// Home.jsx
import React, { useState } from 'react'
import { db } from 'fbase'
import { collection, addDoc, serverTimestamp } from '@firebase/firestore'
const Home = () => {
const [nweet, setNweet] = useState('')
const handleOnSubmit = async (e) => {
e.preventDefault()
const docRef = await addDoc(collection(db, 'nweets'), {
nweet,
createdAt: serverTimestamp(),
})
console.log('Document written with ID: ', docRef.id)
setNweet('')
}
const handleOnChange = (e) => {
const {
target: { value },
} = e
setNweet(value)
}
return (
<div>
<form onSubmit={handleOnSubmit}>
<input type="text" placeholder="What's on your mind?" maxLength={120} onChange={handleOnChange} value={nweet} />
<input type="submit" value="Nweet" />
</form>
</div>
)
}
export default Home
3.2 Getting the Nweets / 느윗 가져오기
// Home.jsx
import React, { useState, useEffect } from 'react'
import { db } from 'fbase'
import { collection, addDoc, getDocs, serverTimestamp } from '@firebase/firestore'
const Home = () => {
const [nweet, setNweet] = useState('')
const [nweets, setNweets] = useState([])
useEffect(() => {
const getNweets = async () => {
const dbNweets = await getDocs(collection(db, 'nweets'))
dbNweets.forEach((document) => {
const nweetObject = {
...document.data(),
id: document.id,
}
setNweets((prev) => [nweetObject, ...prev])
})
// setNweets(dbNweets.map((document) => document.data()))
}
getNweets()
}, [])
const handleOnSubmit = async (e) => {
e.preventDefault()
const docRef = await addDoc(collection(db, 'nweets'), {
nweet,
createdAt: serverTimestamp(),
})
console.log('Document written with ID: ', docRef.id)
setNweet('')
}
const handleOnChange = (e) => {
const {
target: { value },
} = e
setNweet(value)
}
return (
<div>
<form onSubmit={handleOnSubmit}>
<input type="text" placeholder="What's on your mind?" maxLength={120} onChange={handleOnChange} value={nweet} />
<input type="submit" value="Nweet" />
</form>
<div>
{nweets.map(({ id, nweet }) => (
<div key={id}>
<h4>{nweet}</h4>
</div>
))}
</div>
</div>
)
}
export default Home
3.3 Realtime Nweets / 실시간 느윗
현재 구현된 건 새로고침을 해야 다시 DB에 있는 정보를 가져와서 업데이트하는 방식, 하지만 FireStore Database는 Realtime Database이기 때문에 해당 이점을 살리기 위해 리얼 타임을 구현
// Home.jsx
import React, { useState, useEffect } from 'react'
import { db } from 'fbase'
import { collection, addDoc, query, onSnapshot, orderBy, serverTimestamp } from '@firebase/firestore'
const Home = ({ user }) => {
const [nweet, setNweet] = useState('')
const [nweets, setNweets] = useState([])
useEffect(() => {
// 실시간으로 데이터를 데이터베이스에서 가져오기
const q = query(collection(db, 'nweets'), orderBy('createdAt', 'desc'))
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const nextNweets = querySnapshot.docs.map((doc) => {
return {
id: doc.id,
...doc.data(),
}
})
setNweets(nextNweets)
})
return () => {
unsubscribe()
}
}, [])
const handleOnSubmit = async (e) => {
e.preventDefault()
const docRef = await addDoc(collection(db, 'nweets'), {
text: nweet,
createdAt: serverTimestamp(),
creatorId: user.uid,
})
console.log('Document written with ID: ', docRef.id)
setNweet('')
}
const handleOnChange = (e) => {
const {
target: { value },
} = e
setNweet(value)
}
return (
<div>
<form onSubmit={handleOnSubmit}>
<input type="text" placeholder="What's on your mind?" maxLength={120} onChange={handleOnChange} value={nweet} />
<input type="submit" value="Nweet" />
</form>
<div>
{nweets.map(({ id, text }) => (
<div key={id}>
<h4>{text}</h4>
</div>
))}
</div>
</div>
)
}
export default Home
3.4 Delete and Update / 삭제와 업데이트
// Nweet.jsx
import React, { useState } from 'react'
import { updateDoc, deleteDoc, doc } from '@firebase/firestore'
import { db } from 'fbase'
const Nweet = ({ nweet: { id, text }, isOwner }) => {
const [editing, setEditing] = useState(false)
const [newNweet, setNewNweet] = useState(text)
const handleOnClickDelete = async () => {
const ok = window.confirm('Are you sure you want to delete this nweet?')
if (ok) {
await deleteDoc(doc(db, `nweets/${id}`))
}
}
const toggleEditing = () => {
setEditing((prevEditing) => !prevEditing)
}
const handleOnChange = (e) => {
const {
target: { value },
} = e
setNewNweet(value)
}
const handleOnSubmit = async (e) => {
e.preventDefault()
await updateDoc(doc(db, `nweets/${id}`), {
text: newNweet,
})
setEditing(false)
}
return (
<div>
{editing ? (
<>
<form onSubmit={handleOnSubmit}>
<input type="text" placeholder="Edit your nweet" value={newNweet} required onChange={handleOnChange} />
<input type="submit" value="Update Nweet" />
</form>
<button onClick={toggleEditing}>Cancel</button>
</>
) : (
<h4>{text}</h4>
)}
{isOwner && (
<>
<button onClick={handleOnClickDelete}>Delete Nweet</button>
<button onClick={toggleEditing}>Edit Nweet</button>
</>
)}
</div>
)
}
export default Nweet
반응형
'노마드코더 > 트위터 클론코딩' 카테고리의 다른 글
트위터 클론 코딩 #2 Authentication (0) | 2021.10.01 |
---|---|
트위터 클론 코딩 #0 Introduction ~ #1 Set up (0) | 2021.09.08 |
댓글
이 글 공유하기
다른 글
-
트위터 클론 코딩 #2 Authentication
트위터 클론 코딩 #2 Authentication
2021.10.01 -
트위터 클론 코딩 #0 Introduction ~ #1 Set up
트위터 클론 코딩 #0 Introduction ~ #1 Set up
2021.09.08