오늘 만든 것
저번에 Authentication까지 마무리하고 이번에는 nweet 트윗을 전송( + 수정, 삭제)하고 띄우는 것을 완료했습니다.
대부분이 firebase에서 제공해주는 메서드여서 어려움없이 따라갈 수 있었습니다.
Nweeting
App.js
function App() {
const [init, setInit] = useState(false);
const [userObj, setUserObj] = useState(null);
useEffect(() => {
...
}, []);
return (
<>
{init ? (
<AppRouter isLooggedIn={Boolean(userObj)} userObj={userObj} />
) : (
"Initializing..."
)}
</>
);
}
코드가 살짝 수정되었습니다. isLoggedIn state를 삭제하고 이를 userObj의 불린값으로 처리해주었습니다. 그리고 AppRouter에 현재 user를 props로 전달해줍니다. 그리고 라우터에서 Home 컴포넌트에 또 다시 전달해줍니다.
Home.js
function Home({ userObj }) {
const [nweet, setNweet] = useState("");
const [nweets, setNweets] = useState([]);
useEffect(() => {
const q = query(collection(dbService, "nweets"));
onSnapshot(q, (snapshot) => { //데이터베이스에 무슨 일이 있을 때 알림을 받음
const nweetArr = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setNweets(nweetArr);
});
}, []);
const onSubmit = async (evnet) => {
evnet.preventDefault();
try {
const docRef = await addDoc(collection(dbService, "nweets"), {
text: nweet,
creaatedAt: Date.now(),
creatorId: userObj.uid,
});
setNweet("");
} catch (error) {
console.error("Error adding documents: ", error);
}
};
const onChange = (event) => {
그 함수.. 생략...
};
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) => (
<Nweet
key={nweet.id}
nweetObj={nweet}
isOwner={nweet.creatorId === userObj.uid}
/>
))}
</div>
</div>
);
}
Home에 폼을 추가해주었습니다. 텍스트를 입력할 부분과 submit 버튼이 있습니다.

state
nweet는 텍스트 박스에 입력한 트윗입니다.
nweets 여태까지 입련된 트윗 모두를 포함합니다.
useEffect
firebase는 docs를 보는게 더 정확하니 어떤 기능을 하는지만 간략하게 설명하겠습니다.
'nweets'는 Cloud Firestore 데이터베이스의 컬렉션입니다.
해당 컬렌션에 대한 쿼리를 생성합니다. 이때 쿼리를 실행하면 QuerySnapshot 이라는 객체가 반환되는 데 이 객체는 해당 쿼리에 대한 결과 데이터를 나타냅니다.

OnSnapshot() 메서드는 실시간 데이터 업데이트 수신을 위해 사용했습니다. 데이터베이스에 업데이트가 발생하면 자동으로 알림을 받습니다. snapshot을 찍어보면 다음과 같이 docs 프로퍼티를 가지고 있습니다.
data() 메서드를 이용해 docs의 데이터를 가지고 옵니다. 유효한 데이터를 포함한 객체가 포함된 배열로 nweets 값을 갱신해줍니다.

onSubmit
addDoc() 메서드를 통해 데이터베이스의 해당 컬렌셕에 새로운 문서를 추가할 수 있습니다.
text 값으로는 input 텍스트에 입력한 문자열이 되겠습니다. 이때 creatorId는 나중에 수정, 삭제를 위해 필요합니다. 이를 사용해 입력한 사람만 수정하고 삭제할 수 있게 해줍니다.
문서에 추가한 후에는 nweet 값을 빈 문자열로 재할당해줍니다.
이제 트윗들을 보여주기만 하면 됩니다. 이는 Nweet이라는 컴포넌트에서 다룹니다. map을 사용하면 트윗 하나하나에 대한 Nweet을 생성하면 되는데요. Home.js에서는 Nweet에 현재 로그인한 유저와 트윗을 작성한 유저가 같은 사람인지 props로 보내줍니다. 트윗에 대한 정보도 당연히 보내줘야겠죠.
Nweet.js
function Nweet({ nweetObj, isOwner }) {
const [editing, setEditing] = useState(false);
const [newNweet, setNewNweet] = useState(nweetObj.text);
const NweetTextRef = doc(dbService, "nweets", `${nweetObj.id}`);
const onDeleteClick = async () => {
const ok = window.confirm("Are you sure you want to delete this?");
if (ok) {
await deleteDoc(NweetTextRef);
}
};
const onUpdateClick = async (event) => {
event.preventDefault();
await updateDoc(NweetTextRef, {
text: newNweet,
});
setEditing(false);
};
const toggleEditing = () => { ... };
const onChange = (event) => { ... };
return (
<>
{editing ? (
<>
<form onSubmit={onUpdateClick}>
<input
onChange={onChange}
type="text"
value={newNweet}
placeholder="Edit your nweet"
required
/>
<input type="submit" value="update nweet" />
</form>
<button onClick={toggleEditing}>Cancel</button>
</>
) : (
<>
<h4>{nweetObj.text}</h4>
{isOwner && (
<>
<button onClick={onDeleteClick}>Delete</button>
<button onClick={toggleEditing}>Edit</button>
</>
)}
</>
)}
</>
);
}
로그인한 유저가 트윗을 작성한 유저라면 트윗 삭제와 수정 버튼을 보여줍니다.

Edit 버튼 클릭 시 다음과 같이 트윗 수정을 위한 폼이 나타납니다.

state
editing은 트윗 수정을 위함입니다. 평소에는 false이다가 Edit버튼을 클릭 시 true로 바뀌면서 수정을 위한 폼이 보여집니다. Cancel 버튼을 클릭하거나 update nweet 클릭 시 editing은 false로 바뀝니다.
newNweet은 수정폼에 입력한 텍스트 값을 가집니다.
doc() 메서드를 통해 데이터베이스 컬렉션 필드에 접근할 수 있습니다. 이때 userObj.Id를 사용하는데 이는 creatorID가 아니라 addDoc을 통해 새로운 문서를 추가했을 때 자동으로 생성되는 문서 ID입니다.
OnDeleteClick
아주 간단합니다. deleteDoc() 메서드를 사용하면 됩니다. doc()메서드가 반환한 DocumentReference 객체를 인자로 전달하면 삭제할 수 있습니다. 이때 삭제하기 전에 정말로 삭제할건지 사용자에게 물어보기 위해 window.confirm을 사용합니다.
OnUpdateClick
Delete와 비슷합니다. UpdateDoc() 메서드를 통해 DocumentReference 객체와 업데이트할 값을 객체로 전달하면 지정된 필드를 업데이트할 수 있습니다.
이렇게 트윗 전송, 수정, 삭제 기능 완성했습니다.

사실 firebase 메서드가 다해따
'clone' 카테고리의 다른 글
| ntwitter 클론(1) (0) | 2023.03.26 |
|---|---|
| 무비앱 인프런 강의 클론(3) (1) | 2023.03.18 |
| 무비앱 인프런 강의 클론(2) (0) | 2023.03.17 |
| 무비앱 인프런 강의 클론(1) (1) | 2023.03.16 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!