-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
토이프로젝트2_10조_Talkhaja #9
base: main
Are you sure you want to change the base?
Conversation
…o TALK-21--feat/user/hostList
…lkhaja into TALK-6--feat/chat
Refactor: 숙소 채팅 생성 후 채팅방 이름 전송
fix : 채팅방 jwt 수정
…o TALK-18--feat/chat/viewJoin
Refactor: 채팅방 이름관련 수정
Refactor: 숙소와 채팅이 존재하면 미생성 후 이동
Fix: 회원가입, Jwt 토큰 에러 수정
Refactor: 숙소와 채팅이 존재하면 미생성 후 이동
…o TALK-21--feat/user/hostList
…o TALK-20--feat/layout/nav
Fix: Jwtinterceptors 임시 수정
Update README.md
Docs: Update README.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
짧은 기간동안 고생 많으셨습니다!
- rem, px 사용처 구분
- 재사용 가능한 컴포넌트 제작 (mixin과 variable들 제작하셨듯이)
- 일관성 있는 코드 작성 (네이밍, 코드 스타일 등)
- 비동기 작업 실패 시 오류 처리
- 적절한 third party library 검토
- 반복되는 코드 제거
다음 프로젝트에는 위와 같은 사항들을 좀 더 유념해보시면 좋을 것 같습니다!
남은 프로젝트들도 화이팅입니다~
password: string; | ||
name: string; | ||
picture: string; | ||
chats: string[]; // chat id만 속합니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- chats: string[]; //chat id만 속합니다
+ /** chat id만 속합니다. */
+ chats: string[];
JSDoc에 대해 알아보시면 좋을 것 같습니다!
이렇게 작성하시면 에디터에서 편하게 확인하실 수 있습니다.
export interface UserId { | ||
id: string; | ||
} | ||
|
||
export interface UserPW { | ||
password: string; | ||
} | ||
|
||
export interface UserLogin extends UserId, UserPW {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 타입은 request body에 사용되는 것 같은데, 굳이 이렇게 두 타입으로 나누지 않아도 되지 않을까요?
하나가 별개로 쓰일 일은 많지 않을 것 같네요.
import userIdState from '@/stores/atoms/user.atoms'; | ||
import Jwtinterceptor from './JwtInterceptor'; | ||
|
||
const Auth = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
일반적으로, PascalCase로 작성된 함수는 element를 반환함을 의미하는 경우가 많습니다.
이 함수는 custom hook을 목적으로 작성하신 것 같은데, useAuth
처럼 작성해주시는 게 조금 더 맞지 않을까 싶습니다!
const accessToken = getAccessToken(); | ||
const instance = axios.create({ | ||
baseURL: process.env.NEXT_PUBLIC_BASE_URL, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
serverId: process.env.NEXT_PUBLIC_API_KEY, | ||
withCredentials: true, | ||
Authorization: `Bearer ${accessToken}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
request interceptor를 사용해보셨으면 어땠을까요?
한 번 instance를 만들어두고 재사용하실 수도 있었을 것이고, 토큰이 만료된 상황 등에도 좀 더 유동적으로 대응할 수 있도록 제작하실 수 있었을 것 같습니다!
const chatAPI = { | ||
// 특정 채팅방 정보조회 | ||
getChatInfo(chatId: string) { | ||
return instance.get(`/chat/only?chatId=${chatId}`); | ||
}, | ||
// 특정 유저 조회 | ||
getUserInfo(userId: string) { | ||
return instance.get(`/user?userId=${userId}`); | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 함수들이 한 object 내에 있는 이유가 있을까요?
같은 context를 공유할 필요가 없으니, 각기 import해 사용할 수 있도록 따로따로 export해주는 편이 어떨까 싶네요.
@mixin fill-btn() { | ||
border-radius: 5px; | ||
padding: 1rem 2rem; | ||
cursor: pointer; | ||
color: #fff; | ||
background: $light-pink; | ||
border: none; | ||
transition: color 0.3s; | ||
margin: 1rem 0 0; | ||
&:hover { | ||
background: $brand-pink; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mixin
을 활용해 재사용을 시도하신 점은 좋은 것 같습니다.
이런 영역은, Button
같은 atomic한 컴포넌트를 제작해 재사용할 수 있는 컴포넌트를 제작해봤으면 어땠을까요?
styles/_variables.scss
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
가급적 이 곳에 변수들을 모두 선언하고, 폰트 크기, 색상 등이 scss 파일에서 직접 선언되는 일이 없도록 했으면 좀 더 관리하기 좋지 않았을까 싶습니다!
utils/authorizeFetch.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런 파일은, utils/
보다는 api/
에 있는 게 조금 더 어울리지 않을까요?
@@ -0,0 +1,28 @@ | |||
const storage = typeof window !== 'undefined' ? localStorage : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
server side에서 호출 시 오류 없이 아무런 동작을 안 해버리는데, 개발 환경에서는 오류를 터뜨려줬으면 좀 더 디버깅이 편하지 않았을까요?
utils/timeFormat.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
파일에 magic number들이 많네요.
const SECOND_TO_MS = 1000;
처럼 상수들로 관리했으면 좀 더 코드를 읽기 수월해지지 않을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
짧은 기간동안 고생 많으셨습니다!
- rem, px 사용처 구분
- 재사용 가능한 컴포넌트 제작 (mixin과 variable들 제작하셨듯이)
- 일관성 있는 코드 작성 (네이밍, 코드 스타일 등)
- 비동기 작업 실패 시 오류 처리
- 적절한 third party library 검토
- 반복되는 코드 제거
다음 프로젝트에는 위와 같은 사항들을 좀 더 유념해보시면 좋을 것 같습니다!
남은 프로젝트들도 화이팅입니다~
함께 나누어 더 즐거운 여행 수다, Talk하자!
Talkhaja에서 유저들과 함께 여러분들의 여정을 공유하고 즐기세요.
🔐 테스트 계정
🗓️ 개발 기간:
2주(13일) 23.11.06 ~ 23.11.16
👏 Contributors
🛢️ Stack
🛠️ Tools
🤝 Collaboration
🎨 Frontend Stacks
⚙️ Backend Stacks
💾 Git Branches
✅ 요구 사항
필수 구현 사항
✅
useState
,useReducer
를 활용한 상태 관리 구현✅
Sass
또는styled-component
를 활용한 스타일 구현✅
react
상태를 통한 CRUD 구현✅ 상태에 따라 달라지는 스타일 구현
✅
custom hook
을 통한 비동기 처리 구현✅ 유저인증 시스템(로그인, 회원가입) 구현
✅
jwt
등의 유저 인증 시스템 (로그인, 회원가입 기능)✅ 소켓을 이용한 채팅 구현
선택 구현 사항
✅
Next.js
를 활용한 서버 사이드 렌더링 구현✅
typescript
를 활용한 앱 구현💻 커밋 컨벤션
📁 폴더 구조
💭 개인별 작업 내용
서지수
작업 세부내용
회고
팀장을 맡게되면서 많은 부담과 걱정이 있었다. 하지만 이번 프로젝트의 팀장 경험은 나에게 많은 의미가 있었다. 실력 부족, 일정 관리, 역할 분배 등의 걱정이 있었는데 실력 부족은 프로젝트를 진행하면서 공부, 팀원들과의 공유를 통해서 극복할 수 있었고 일정 관리, 역할 분배는 노션, 지라등의 협업 툴을 이용해 팀원들의 작업 상황, 남은 작업 파악, 각자의 진행 상황에 따른 잔업 분배 등을 효율적으로 할 수 있었고 다음 프로젝트에서도 팀원으로서 팀장 및 다른 팀원에게 나의 상황 공유을 잘 해야겠다고 생각했다.
저번 프로젝트에서 가상화폐 데이터 소켓 연결 경험이 있어서 이번 채팅 소켓 연결과 수월할 것이라고 생각했는데 소켓 연결 후 일방적으로 데이터를 받기만 했던 전 작업과는 다르게 채팅 소켓 연결은 쌍방 소통이 필요한 작업이라 차이가 있었다. 소켓 연결 후에 입/퇴장, 메세지 수신/발신 등의 작업이 있어서 다른 방식의 소켓 연결 작업도 경험할 수 있었다.
또한, API의 에러 처리 및 에러 코드가 상세하게 구분되어있지 않아서 팀원들과 함께 개발자 도구의 네트워크 탭을 분석할 일이 많았는데 이 경험을 통해서 앞으로 백엑드에 무작정 '안돼요...'하기 보다는 네트워크 탭을 분석해서 원인을 찾는 방법을 알게 되었다.
이번 프로젝트을 통해서 이전에 Next 경험이 있었지만 작업에서 단순 Next의 문법만 따랐을 뿐이지 Next의 기능은 전혀 사용하지 않았다는 것을 알게되었고 앞으로 SSR에 대해서 공부해야겠다고 생각했다.
마지막으로 팀원 한분한분에 대해서 회고 및 감사를 적었지만 리드미가 날라가는 바람에... 따로 전달하기로 하고 여기서는 팀원 모두에게 감사을 전합니다^^
김지민
💭 채팅 주요 기능
🎨 디자인
💣 트러블 슈팅
❌오류
Duplicate atom key "userIdState". This is a FATAL ERROR in production. But it is safe to ignore this warning if it occurred because of
hot module replacement.
분명 atom은 하나인데 자꾸 이런 오류가 떴습니다.
찾아보니 Next.js에서 build를 하면 atom을 저장해두는데 이것 때문에 두개로 중복된다고 Next.js에서 판단한다는 유명한 오류였습니다.;;
✔️ 해결
RecoilEnv.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED = false;
.App.js 파일 상단에 추가하니 오류가 사라졌습니다!
--
❌오류
socket을 두번씩 생성되는 오류가 있었습니다. 이 때문에 소켓 connect가 제대로 이루어지지 않았습니다.
✔️ 해결
next.config.js 파일에서 reactStrictMode: false 를 해주었습니다.
react에서는 reactStrictMode: true이면 render가 강제적으로 두번씩 된다고 합니다!
또한 무한 소켓 연결을 막기 위해 useMemo를 사용하여 소켓을 생성해주었습니다
--
❌오류
socke을 connect 했음에도 불구하고 fetch-messages가 서버로 전송되지 않는 에러
✔️ 해결
setTimeout을 사용해 소켓에 요청이 들어갈때까지 요청을 보냈습니다.
--
❌오류
채팅방에서 text를 작성해 onChange 이벤트가 발생하면 상관없는 userId API를 호출하는 오류
✔️ 해결
userId API를 useEffect로 감싸서 의존성 배열에 chatId로만 변경하였습니다.
--
❌오류
Image is missing required "src" property:
✔️ 해결
소켓에서 받아오는 대화정보는 userId만 받아와서 해당 userID의 정보를 API요청으로 받아줄때
유저 이미지를 useState('')값으로 초기화를 했더니 발생한 오류였읍니다.
src 에userImage의 경로가 들어가긴 하지만 Nextjs에서 제공하는 Image태그는 src값을 절대 빈값으로 받지않아 발생는 오류였습니다. 따라서 response로 받아오는 이미지 url값이 있을때만 해당 Image 태그를 반환하게 수정하였더니 해결되었습니다
회고
react에서 소켓 연결은 처음이라 정말 많은 우여곡절이 있었다.:sweat_drops: 소켓 연결 시도하면서 너무 막막했지만 팀원들 덕분에 다같이 해결할 수 있었다 + 멘토님 :fire::fire:
진짜 채팅 기능 구현 못할 것 같았는데 해냈다..도와주신 팀원분들 모두 감사합니다!:+1::+1:
scss를 처음 사용해보았는데 생각보다 편리해서 좋았다 css를 상속할 수 있다는게 진짜 편리한 것 같다.
axios를 사용해서 API 연결했는데 처음에는 에러 코드가 너무 세분화 되어있지 않아서 불편했는데 덕분에 네트워크 탭을 마스터 한 것 같아서 뿌듯하다..이제는 어떠한 네트워크 오류가 발생해도 해결할 수 있을 듯한 느낌:+1:
어찌보면 간단한 기능을 구현하는 거라고 생각했는데 생각보다 시간이 걸렸고 꽤나 어려움을 느꼈다.. 그리고 이번에도 Next.js를 제대로 활용하지 못한 느낌이라 아쉬웠다..
소켓 연결에 시간을 많이 뺏겨 SSR을 제대로 공부하고 사용할 시간적 여유가 없었어서 아쉬웠다..!
그래도 협업하는 법을 다시 한 번 알게되었고 또, 처음으로 zira를 사용해볼 수 있어서 좋았다!
하지만 아무래도 공통 컴포넌트를 개인적으로 작업하는 건 한계가 있는 것 같아서 다음 프로젝트에서는 꼭 storybook을 사용해 봐야겠다!
박준규
수행 역할
발생했었던 이슈
위와 같이 소켓을 통해 받아온 데이터였는데, 초반에
Join
을 통해 받아오는 데이터는leave
의 데이터들과 달리 api에 불필요한 더미 데이터들이 같이 전송되어 필요한 부분만 추출하여 사용함에 있어서 애를 먹기도 했었지만 데이터는 성공적으로 받아 왔는데, 원인을 알고나니 스스로 기본기가 정말 많이 부족함을 느꼈다..useState를 사용함에 있어서 사용이 끝난 직후 state값을 초기화 해주는 작업을 제외하고 작업을 진행하다 보니, 예상과는 다른 값들이 도출되어 문제가 발생했던 것이다. 이후 값을 초기화해주는 코드를 넣고 작업을 진행했는데, 다행히 정상동작함을 확인할 수 있었다.
이 이후에도 채팅방에서 특정 유저를 조회하여 해당 유저의 사진정보와 이름 등을 받아오는데 원인모를 문제때문에 6시간이 넘도록 앉아있기도 했었는데, 결국은
api를 요청하는 주소의 오타
때문인 것을 알고 난 뒤에는 정말이지 그렇게 허무할 수 없었다..ㅠㅠ다행히 그렇게 큰 이슈는 아니었지만,
console.log를 찍어서 잘 보내고 잘 받아오는지 확인하기
,외부 데이터를 사용할때는 오타가 있는지 확인하기
등 개발을 함에 있어서 항상 내가 올바르게 하고 있는지 수시로 확인 할 필요가 있음을 뼈저리게 느끼게 되었다.회고
이번 기간동안 가급적 많은 도전과 시도를 통해서 많은 공부를 해야했던 좋은 기회였음에도 불구하고,
그러지 못했음에 다소 아쉬움이 남았다.
2주라는 짧은 기간에 Next.js나 recoil(이번 프로젝트때 한번도 사용해보진 못했지만..) socket 등의 기술들을 가지고 결과물을 만들어내는것이 쉬운 일도 아니었을 뿐더러, 특히 우리조의 API-key에 이슈가 있어 개발도중 난항을 겪기도 했었지만
부단하게 노력하며 밤을 지새우면서까지 나를 가르쳐준 우리 조장과 팀원들 덕에 결국 프로젝트를 마무리할 수 있게 되었다.
사실 이번 프로젝트 기간동안 약간의 슬럼프가 찾아오기도 했었다.
'지금까지 달려왔는데도 실력도 크게 늘지않고, 도통 어떻게 해야할지 잘 모르겠다'
는 생각도 자주 들었었고,'이런 간단한 것 조차도 구현하는데 있어서 많은 시간이 걸리는걸 보니, 나는 사실 개발에 재능이 없을지도 모르겠다'
는 생각도 들고,
'미니 프로젝트를 진행하기 이전에 개발자를 포기해야하나'
라고 혼자 고민을 하기도 했었다.하지만 구현한 기능이 아무리 적더라도 성공적으로 구현하는데 목표를 두고 도전해보라며 격려해주시던 유영매니저님과 팀원들, 그리고 스터디그룹원들의 응원 덕분에 다시금 키보드를 잡고 오랜만에 꺼져가던 열정에 다시 숨을 불어넣었고,
목표했던 기능들의 구현을 성공적으로 마칠 수 있었다.
어찌보면 항상 강의장에서 다른 수강생들과 함께 머리를 맞대며 공부를 이어나가는 수강생들과는 달리 4개월이 넘는 시간동안 어두컴컴한 방에 틀어박혀 작은 글씨들을 보고 있으니 몸과 마음이 지칠만도 하다. 게다가 새로운 기술을 배우는데 있어 남들보다 조금 더 천천히 내가 원하는대로 뜯어보며 배워가는 타입이다 보니, 빠르게 성장하는 다른 팀원들의 모습에 자존심도 상하고, 조바심이 나기도 했었다.
하지만 이번 프로젝트를 말미암아 내 스스로 어떤 공부를 해야하는지, 현재 내가 어떤 상황에 놓였는지에 대해서 조금 더 진지하게 생각할 수 있었던 계기가 된 것 같다. 지금 당장은 가파른 성장을 이루지 못하더라도, 언젠간 깊은 뿌리를 내려 큰 결실을 맺을 수 있는 거목같은 개발자가 되리라고 스스로 다짐해본다.
어준혁
작업 내용 요약
로그인 기능 구현
회원가입 기능 구현
마이페이지 기능 구현
후기
프로젝트를 진행할 때 항상 리액트를 사용했었다. 그래서 팀에서 넥스트를 사용한다고 하였을 때 조금은 겁이 났다. 토이 프로젝트가 끝나고 한달이나 시간이 있었는데 공부를 안한 내 자신이 후회스러웠다. 프로젝트가 시작되고 공부를 하면서 구현을 하기 시작했다. 하지만 CSR에 익숙했던 나는 넥스트의 장점을 전혀 살리지 못한 코드를 작성하고 있었다. 그래서 시간이 걸리더라도 SSR기반의 코드를 짜보자고 다짐하여 getServerSideProps를 사용하면서 넥스트에 재미가 붙기 시작했다. 또 팀원들과 패스트캠퍼스 강의장에서 다같이 작업하다보니 시너지 효과가 발휘되어 개발에만 전념할 수 있었다. 이 프로젝트를 진행하고 새로운 기술에 대한 호기심이 더욱 더 생겼고 개발이 더 재밌어졌다. 이런 마음을 오랫동안 유지하고싶다.
윤지영
작업 내용
숙소 목록 페이지
하단 고정 내비게이션
오픈 채팅 목록 시간 표시 포맷팅
작업 중 어려웠던 점
제공된 api만으로는 숙박업체 유저와 일반 사용자 유저를 구분하기가 쉽지 않았는데 다행히 프로젝트 시작 후 금방 진행된 멘토님의 조언 덕분에 덜 헤매고 수월하게 작업 할 수 있었다!!
하지만 프로젝트 종료일 직전 효율적인 코드를 위해 데이터를 읽고 쓰는 방식을 변경하기로 하면서 그에 따른 코드변화가 도미노처럼 줄줄이 이어졌다. 사실 하나하나씩 차근차근 보면 별 거 아닌 것 같은데 금방 끝날 것 같던 작업이 끝나지 않으니 마음이 점점 더 조급해져 갔다. 처음부터 충분히 고민해보고 잘 설계 후에 작업 했다면 훨씬 여유롭게 프로젝트를 마칠 수 있었을 것 같아 아쉽다. 매 작업 시 느끼는 어려운 점이 설계 단계인 것 같다. 직접 코드를 짜기 전까지는 가늠이 안된다..작업 시간도 구조 설계도...더 많이 배우고 경험해봐야 할 것 같다!
회고
급변하는 프론트엔드 세계에서 항상 새로운 라이브러리와 새로운 프레임워크들을 익혀야 한다는 점이 항상 마음의 짐처럼 쌓여 큰 부담으로 다가왔었는데 이번 프로젝트를 통해 새로운 것들을 익히는 것에 대한 부담감을 많이 줄일 수 있던 것 같다. 아무래도 다양한 것들을 많이 사용해 볼수록 각 라이브러리들의 편리함을 체감할 수 있게 되어 그런 것 같다. NEXT.js를 본격적으로 사용해 본 적은 처음이었는데 많이 낯설지 않아서 좋았다. 하지만 낯설지 않았단 점은 NEXT.js의 장점을 충분히 활용하지 못했기 때문 인 것 같다..😂 api라우트를 사용하지 못한 점이 너무 아쉽다. 또 기능별 커밋이 아닌 페이지별 작업하는 아주 나쁜 습관이 쉽게 고쳐지지 않는다😂..하루 빨리 고칠 수 있도록 노력해야겠다! 좋은 조장님과 팀원들, 그리고 멘토님을 만난 덕분에 프로젝트를 잘 마무리 할 수 있었던 것 같다. 단순히 역할을 나눠 각자의 기능 개발을 하기 보단, 작업 현황과 결과물을 보며 이 작업은 어떻게 개선되면 좋을지에 대한 피드백을 말해주셔서 특히나 많은 것들을 접하고 배울 수 있었다. 문제를 해결하기 위한 접근 방법들도 차근차근 알려주셔서 수정작업도 즐겁게 할 수 있던 것 같다. 이번 프로젝트를 되돌아 보니 도움받은것들 뿐이어서 많은 아쉬움이 남는다. 팀원들에게 도움되는 사람이 될 수 있도록 분발해야겠다🔥