~77일차~
9/11 ~ 9/22 총 2주에 걸쳐 팀으로 짜여진 토이프로젝트가 진행되었다.
개발버전 : https://heartfelt-mandazi-9dce7c.netlify.app/
깃 레포지토리 : https://github.com/noSPkeepgoing/Wikipage-team12
노션 : https://www.notion.so/7a5c2df8aaf7413982f8895d96d4db07
우리 조는 타이머를 포함한 스터디 사이트를 만들었고,
내가 맡은 파트는 갤러리 페이지 구현이었다.
firebase를 사용하여 이미지 및 댓글을 저장 및 가져오기, 삭제를 구현.
gsap을 이용한 슬라이드를 구현.
session storage의 현재 로그인 유저의 정보를 가져와 사용.
내비바에서 카테고리명 클릭 시 해당 슬라이드로 이동
이미지를 업로드한 작성자 본인에게만 버튼이 보이도록 부여
프로젝트를 진행하기 직전 주에 TS와 React 강의 2차가 예정되어 있었는데 강사님의 사정으로 인해 그 주의 강의가 모두 취소 되었었다.
프로젝트를 위해 그 주에 온라인 강의나 다른 강의를 듣기는 했지만 역시 강의를 듣는 것과 직접 하는 것은 달랐다.
초반에는 공부를 다시하며 시작해서 속도가 붙지 않았지만 갈수록 익숙해지는 것이 느껴졌고, 확실히 코딩은 직접 부딪히는 게 답이라는 걸 몸소 체험하게 되었다.
이번에 부딪힌 문제와 에러메세지는 사실 기초적인 것이라 할 수도 있겠지만, 그래도 프로젝트 중간중간 마주친 문제들을 나열하며 복기해보려 한다.
댓글을 쓰고 읽는 데 전혀 작동을 하지 않았고, 나중에 처음부터 다시 뜯어보니 prop을 내리는 중 실수가 있었다.
userImage={userImage}
라고 적어야 했는데 userImage
만 적었던 것.
처음에는 useEffect를 막연히 어렵게만 생각해서, useState만 사용해서 DB에 저장을 하려 했다.
그러니, 댓글을 적을 때 한템포씩 느리게 저장되었고 useEffect를 사용해 이부분이 쉽게 해결되었다.
: .map is not a function
comment 및 유저정보로 이루어진 객체가 여러개 들어있는 commentList
가 있다.
여기에 map을 사용하여 뿌려줘야 했는데,
commentList.map ...
이 부분에서 계속 작동을 하지 못했고, 아주 오래 붙잡다 다시 살펴보니... useState의 초기값을 []으로 하지 않아서 commentList 가 객체로 인식된 상태였다.
처음에는 useEffect로 충분히 구현할 수 있을 거라 생각했는데 그러지 못했고, firebase에서 제공하는 onSnapshot을 이용해 새로고침 없이도 댓글을 제출하면 firebase가 실시간으로 변경을 인식해 주는 로직을 사용했다.
function realtime() {
const fetchList = (categoryId: any, imgId: any) => {
// 유저가 선택한 카테고리와 이미지를 doc,과 field 명으로 받음
const userRef = doc(db, categoryId, imgId);
//onSnapshot으로 데이터를 받아 set
const unsub = onSnapshot(userRef, (doc: any) => {
setCommentList(doc.data().comments);
});
return unsub;
};
return fetchList(categoryId, imgId);
}
useEffect((): any => {
if (comment !== '') {
uploadCommentList(imgId, categoryId, comment);
realtime();
}
setComment('');
}, [isChange, doc, onSnapshot]);
현재 filter는 댓글 당 id값을 주어 해당 내용이 많이 달라졌지만 처음의 코드 구현은 이러했다.
지울 댓글의 내용과 작성자 아이디를 비교해서 불일치하는 것만 남기는 filter를 사용하려 했다.
(이미지 상에서는 에러로 인해 댓글의 내용으로만 먼저 테스트 중)
하지만 댓글이 전혀 지워지지 않았고,
분명 콘솔을 찍어봐도 지워야 할 내용과 지울 내용이 겹치는 부분이 있었다.
comment.text와 getDelText가 같다면 true값이 나오도록 했는데, 보기에 값은 값이 있어도 false만 나오고 있는 상황이었다.
그러다 문득 생각난 게 trim()이었고... trim을 사용하니 너무 가뿐히도 해결되는게 어이없기도 하고 속편하기도 했다.
innerHTML를 사용한다면 trim()을 잊지말자.
Cannot read properties of null (reading 'useContext') TypeError: Cannot read properties of null (reading 'useContext')
구글링했을때 주로 꼽는 원인은 다음과 같다.
1. 설치를 다 했는지
2. import를 제대로 했는지
3. hook 사용 할 때 function안에서 썼는지
나 같은 경우 3번이었다. 수정하니 바로 잘 되었다.
thanks to https://forum.moralis.io/t/solved-cannot-read-properties-of-null-reading-usecontext/21126/5
TS에서 제대로 타입을 사용하지 못한 것과, React에서 useState 나 더 다양한 Hook들을 활용하지 못한게 아쉬웠다.
곧 한 달간 TS, React를 배운 다음 토이프로젝트2, 미니프로젝트, 파이널프로젝트가 쭉 이어지게 될텐데 한달 간 정진해서 다음 토이프로젝트부터는 지금보다 더 수월하게 진행하고 싶다.
우선, 팀으로 프로젝트를 진행하는 것에 걱정이 많았는데 다들 너무 좋은 분들이라 배워가는 부분이 정말 많아 좋았다.
조원 분들께 누가 되고 싶지 않아 잠도 줄이고 주말도 없이 불태웠는데 힘든지도 모르고 꽤 재밌게 했던 것 같다.
그리고 이번 프로젝트를 통해 부트스트랩이나 SCSS도 사용하게 되었는데 생각보다 더 쉬워서 너무 좋았던 기억이 난다.
난 뭐든 완벽히 하고싶다는 생각에 무언가를 시작하는 것에 괜히 큰 마음을 먹고 시작해야 하는 좋지않은 버릇이 있었는데, 이번 프로젝트를 통해 그런 습관을 고치게 된 것 같았다.
코드는 되돌리기가 가능하니 겁먹지 말고 뭐든 시도해보자.