굉장쓰하게 바쁜 연휴였다.
연휴 내내 코드를 본 기억 뿐이다. 하지만 재밌었다. 이번에 내가 맡은 기능들이 좀 중요하면서도 어려울 수 있겠다고 생각해서 선택했는데 내 예상이 맞았다.
< 목차 >
1. 개발자 커뮤니티 구현
2. 문제 : 해결책
① 작성일시 추가했더니 글 새로 추가하면 화면에 아무것도 안 뜸
② [Edit 버튼 클릭] 클릭한 게시물의 id를 갖고 Write Page로 넘어가서 해당 게시물의 내용이 보여야 하는데 안 뜸
③ import 절대 잊지 말기
④ 내가 맡은 페이지, 기능 구현 완료
⑤ "상태 관리는 어떻게 하죠?"
⑥ [Write Page] 새 게시글 작성을 누르면 아무것도 안 보임
3. 금일 소감
1. 개발자 커뮤니티 구현
우리 팀은 'Devtiny'라는 개발자 정보 공유 커뮤니티가 콘셉트다.
'Developer' + 'Destiny'의 합성어로, 개발자가 운명인 사람들을 의미한다. 다시 생각해도 작명 정말 잘한 것 같다.
암튼 주요 기능은 Firebase의 DB를 활용한 로그인, 회원가입, CRUD 기능이다. 나는 CRUD(Create, Read, Update, Delete / 생성, 조회, 수정, 삭제) 기능을 맡았다.
구현하며 생긴 문제와 해결 과정은 다음과 같다.
2. 문제 : 해결책
① 작성일시 추가했더니 글 새로 추가하면 화면에 아무것도 안 뜸
'? 뭐가 문제지' 하다가 VS Code상에도 빨갛게 에러가 뜨는 부분인 날짜 코드를 수정했다. 날짜 코드를 좀 더 명확하게 지정해줬더니 화면이 정상적으로 나왔다.
위에 하이라이트 처리된 부분이 새 저장소에 작성일시를 저장하는 코드다(이렇게 이해하면 쉽다).
위 코드를 포함해, Firestore에서 데이터를 불러오는 코드는 다음과 같다.
// Firebase에서 데이터 가져오기
useEffect(() => {
const fetchData = async () => {
// posts라는 이름으로 되어있는 컬렉션의 쿼리값 가져옴
// 쿼리값을 토대로 가져온 다큐먼트들을 '쿼리스냅샷'으로 담음
// getDocs 메서드를 통해 collection에 있는 모든 다큐먼트 가져옴
const querySnapshot = await getDocs(collection(db, 'posts'));
// 최초 게시물을 배열로 선언
// doc에 메타 데이터까지 들어가있기 때문에 실제 데이터는 doc.data로 가져올 수 있음
// querySnapshot에 들어가있는 모든 doc에 대해서 initialPosts값을 추가한 다음,
// initialPosts를 setPosts를 통해서 값을 넣어줌
const initialPosts = querySnapshot.docs.map((doc) => ({
// doc에 id값을 추가해서 posts 추가
id: doc.id,
...doc.data(),
// createdAt을 적절한 날짜 형식으로 변환
createdAt: doc.data().createdAt?.toDate().toLocaleString()
}));
setPosts(initialPosts);
};
fetchData();
}, []);
// addDoc으로 데이터 추가, updateDoc으로 수정 로직
// async - await 더 공부하기
const addOrEditPost = async (event) => {
event.preventDefault();
// Firestore에 데이터 추가
// 어느 collection의 문서를 가져올지 지정, 2번째 인자로 어떤 값을 추가할지 지정
// 코드를 작성할 때 비동기 함수를 사용하는 경우, 항상 try...catch 블록을 사용하여 예외 처리를 해주는 것이 좋음
if (!title.trim() || !content.trim()) return; // 빈 제목 또는 내용 방지
try {
if (isEditing) {
// 글 수정 로직
const postRef = doc(db, 'posts', editingPostId);
await updateDoc(postRef, { title, content });
alert('게시물이 수정되었습니다!');
} else {
// 새 글 추가 로직
await addDoc(collection(db, 'posts'), {
title,
content,
createdAt: Timestamp.now(),
isDone: false
});
alert('게시물이 추가되었습니다!');
}
// 상태 초기화
setTitle('');
setContent('');
setIsEditing(false);
setEditingPostId(null);
fetchData(); // 여기서 fetchData를 호출하여 게시물 목록 갱신
} catch (error) {
console.error('Error adding/editing document: ', error);
}
};
② [Edit 버튼 클릭] 클릭한 게시물의 id를 갖고 Write Page로 넘어가서 해당 게시물의 내용이 보여야 하는데 안 뜸
링크에서 힌트를 얻어, 주소값과 관련된 모든 코드를 보고 답을 알아냈다.
하이라이트 처리한 부분, 즉 주소에 id를 안 넘겨줘서 그랬다............... 기능을 추가할 때는 늘 코드를 전체적으로 보고, 변경하거나 추가해야 하는 사항을 체크하자
③ import 절대 잊지 말기
뭐지?? 왜지??? 하다가 import가 안 됐단 걸 깨달았다......
import { getDoc, addDoc, collection, getDocs, deleteDoc, doc, updateDoc, Timestamp } from 'firebase/firestore';
어이없는 휴먼 에러 금지....
④ 내가 맡은 페이지, 기능 구현 완료 (필수 기능이 아닌 이미지 업로드는 아직 연결 안 함)
일단 데드라인 내에 완성하는 게 먼저니까 최대한 후다닥 해서 일요일 늦은 밤에 완성해서 Push 했다. 코드를 전체적으로 수정하는 작업이 필요하긴 한데 일단 돌아는 가고 필수 기능도 다 넣어서 약간 마음이 편해지고 또 뿌듯했다.
필수 기능이 아닌 이미지 업로드는 posts를 전역 상태로 한 뒤에 연결해서 보여지게 할 생각이다. 일단 뼈대만 만들어둔 상태다.
⑤ "상태 관리는 어떻게 하죠?"
뿌듯해하고 있던 중, 어떤 팀원 분이 상태 관리에 대한 질문을 하였다.
"상세 페이지에서 해당 유저의 글인지 어떤 방법으로 확인하고 수정, 삭제 버튼을 보여주죠?"
곰곰히 생각해보다가 해결책이 뭘지 추론으로 접근해보았다. 내가 내린 추론은 다음과 같다.
User의 e-mail(식별자)을 포함한 정보가 있는 State를 최상단 컴포넌트에서 선언
→ User가 로그인, 회원가입을 하면
→ e-mail 값을 가지고 Main Page로 이동됨
→ 글 하나를 클릭했을 때, 해당하는 id의 글이 보이게 함
→ 수정, 삭제 버튼은 클릭한 User의 e-mail이 맞는지 확인한 다음에 맞으면 보여주고 아니면 안 보이게 null 처리
튜터님께서도 들으시곤 맞다고 하시면서 Auth DB가 전역에 있으니 거기서 E-mail과 닉네임을 담을 것을 하나 더 선언해서 가지고 있으라고 하셨다. 그 담은 것을 Posts에다가 e-mail과 nickname으로 각각 추가해서 게시글을 생성하면 된다고 하셨다. 데이터베이스 구조.. 재밌다..... 나중에 추가적으로 공부해야겠다.
다만 이 결론을 얻기까지 2시간 정도 회의를 했기 때문에, 앞으로는 이런 비효율적인 회의 시간을 갖지 않아야 한다고 하셨다. 그래서 해결책 의논 전에 문제가 명확하게 무엇인지 정의하고, 서로의 코드를 이해하는 게 필요할 것이라고 말씀하셨다. 정말 중요한 말씀이라 듣는 즉시 뇌에 새기기 위해 완전 집중하고 되새겼다.
더불어, 사용자의 이메일을 가져오는 코드는 다음과 같다.
import { useEffect } from 'react';
import { auth } from '../firebase'; // Firebase 설정 파일에서 auth 인스턴스를 가져옴
useEffect(() => {
const user = auth.currentUser;
if (user) {
console.log(user.email); // 현재 로그인한 사용자의 이메일 주소 출력
// 여기에서 user.email을 사용하여 필요한 작업을 수행할 수 있음
}
}, []);
⑥ [Write Page] 새 게시글 작성을 누르면 아무것도 안 보임
안 넘어가지니, 뭔가 경로 문제인 것 같다 싶어서 Router 경로에 id가 추가되지 않은 주소를 추가해봤더니 정상적으로 새 게시글 작성이 나오는 걸 확인할 수 있었다.
3. 금일 소감
내 페이지의 기능은 전부 구현했지만 팀원분 두 분이 아직 HTML, CSS, JS 다 포함해서 전체의 5%도 시작이 안 되어 있으셔서 얼른 도와드려야겠다 싶었다. 그래서 내가 구현한 코드는 일단 두고 나처럼 본인 페이지, 기능 구현이 완료된 팀원 한 분과 페이지를 나눠서 맡았다.
우리 팀은 총 4명으로, 나 포함 2명은 필수 기능 구현이 완료되었고 다른 두 분은 구현이 안 되어 있어서 각각 한 분씩 맡은 페이지를 돕는 방향으로 정했다. merge를 최종 제출 직전날엔 해야 되기에 시간이 하루밖에 없어서 당장 시작하기로 하고, 다른 팀원분의 페이지를 구현했다.
구현하지 못하신 팀원분들께는 필수 기능 중에 하나를 구현하실 수 있게끔 공부해야 할 것을 알려드리고 언제까지 하시라고 과제처럼 드렸다. 그러고 약속한 시간에 체크하고 어떤 부분에서 공부를 하셔야 하고, 어떤 방법으로 공부를 해나가셔야 하는지 구체적으로 명확히 말씀드렸다.
나조차도 불과 며칠 전까지 그랬으니 공감도 가고 그 답답한 마음이 이해가 가서 최대한 도움을 드리고자 말씀드렸다. 일단 기능 구현 하나 더 남아서 마저 해야겠다. 파이팅!!!
'[Front-end] 개발자 공부' 카테고리의 다른 글
[개발 공부 37일차] 프로젝트 완성! 발표 직전날 (1) | 2024.02.15 |
---|---|
[개발 공부 36일차] Devtiny Merge | News Feed (0) | 2024.02.13 |
[개발 공부 34일차] To-do List 구현 (2) | 2024.02.08 |
[개발 공부 33일차] Counter 구현 (1) | 2024.02.06 |
[개발 공부 32일차] 앞으로의 공부 방향성 | 개인과제 완료! (2) | 2024.02.05 |