프로젝트 소개
- 주제 : 타임라인 기반 공부 피드 SNS
- 기간 : 2024. 02. 13 ~ 2024. 02. 29 (약 2주)
- 팀원 구성 : 프론트엔드 3명, 백엔드 3명
개발환경
-
Front
- Next.js, React, tailwind, Javascript
-
Back
- Spring boot, MySQL, multipart
-
Etc
- Redux, Redux-persist, Next-auth, Websocket
-
Collaborate & Tools
- Git, GIthub, Figma, Notion
개발 포인트
1. 컴포넌트 모듈화
- 사전 회의를 통해 공통 부분이 있는 컴포넌트를 하나로 작성해 코드 재사용성을 높이고자 했습니다.
- 스톱워치를 다른 컴포넌트에서도 재사용할 수 있게 커스텀훅으로 만들었습니다.
2. 새 기술 사용 : 이전 프로젝트에서의 부족함 보완
2-1. SSR 프레임워크 Next.js
- 지난 프로젝트에서 SEO가 어려운 React의 한계를 느껴 리액트 기반의 SSR 프레임워크인 Next.js를 사용했습니다.
- 메타데이터를 활용해 SEO를 고려했습니다.
- 14 버전에서 제공하는 Loading UI를 사용해 페이지 로딩 시간이 길 경우를 대비했습니다.
2-2. 유틸리티 CSS tailwind
- 지난 프로젝트에서 SASS를 사용하며, 스타일링을 위한 CSS를 마치 HTML처럼 작성하고 있다는 불편함을 느꼈습니다.
- 이를 해소하고자 유틸리티 퍼스트 CSS 프레임워크인 tailwind를 사용하여 목적에 맞는 코드 작성에 집중했습니다.
- 공통 설정을 config 파일에 추가하여 일관된 스타일링을 유지하려고 했습니다.
3. 웹소켓 : 실시간 알림
- 단순 알림 기능 구현이 목표라서 상대적으로 가벼운 Websocket API을 사용했습니다.
- Websocket API는 헤더에 값을 담을 수 없어서 쿼리스트링으로 토큰을 전달해 로그인 시 소켓을 오픈했습니다.
- 쿼리스트링으로 JWT 토큰값 전달하고, JSON 형식으로 역직렬화/직렬화하여 데이터를 송수신했습니다.
4. 카테고리 클릭 시 svg아이콘 색 채우기
- UX 향상을 위해 선택한 카테고리의 색을 채웠습니다.
- 여러 svg 파일을 하나의 컴포넌트 내에서 export하여 아이콘을 편리하게 관리했습니다.
- onClick 이벤트 발생 시 현재 인덱스값을 state에 설정된 인덱스 값과 비교 후 해당 인덱스에만 색깔을 props로 전달했습니다.
개발 상세 내용
1. 헤더
[Left]
- 카테고리 클릭 시 UX를 고려하여 해당하는 아이콘의 색이 채워짐
- ‘내 공부’에서 Todo 생성/삭제하면 To Do 리스트에도 실시간 반영
- 공부 내용 입력 후 START 클릭 시 타이머 동작
- 타이머 시작 or 정지 → 웹소켓으로 실시간 통신 내용이 메인에 표시
- 톱니바퀴 아이콘 hover 시 정보 수정/로그아웃 페이지 이동
[Top]
- 누적 공부 시간이 높은 순으로 유저 10명 슬라이더(
Swiper.js
)로 표시
2. 메인
- 자신의 공부 상태(시작, 끝)를 모아볼 수 있는 공간
- 현재 시각을 기준으로 작성일 표시
- 스톱워치 상태(시작, 일시정지, 끝)에 따라 아이콘을 다르게 적용
3. Todo 생성 삭제 연동
- 유저가 ‘내 공부’에서 Todo 작성 및 삭제 시 헤더에 반영
- boolean 값을 전역에 설정하여 useEffect의 디펜던시로 동작
트러블 슈팅
💡 JSON으로 데이터를 주고받을 때 필요한 작업
- 상황 : Websocket은 텍스트와 바이너리만 포함 가능해서 JSON으로 서버와 데이터를 송수신했다. 그런데 서버(spring boot)에서 보낸 객체가 클라이언트 측에선 string으로 읽히는 문제 발생.
- 원인 : JSON 형식으로 데이터를 전송할 땐 직렬화를, 데이터를 읽을 땐 역직렬화 과정이 필요하다. 즉 문자열로 변환한 서버 측 데이터를 다시 원래의 객체로 변환하는 작업(
JSON.parse
)이 누락된 것.
- 해결 : 메시지를 전송할 땐 JSON으로 변환(
stringfy
)하고, 받아올 땐 역직렬화(parse
)를 통해 객체 데이터를 처리.
💡 배열 객체 비교
- 상황 : 사용자가 작성한 Todo 리스트가 달라질 때만 state에 새 배열을 담으려고 했습니다. 이를 위해 동등 연산자(
===
)를 사용했는데 배열 요소의 비교가 제대로 이루어지지 않았습니다.
- 원인 : 원시형과 달리 참조형은 값이 아닌 참조 주소를 저장한다. 즉 할당된 메모리 주소가 다르면 값이 같더라도 다르다고 인지함.
- 해결 : 방법은 둘 중 하나다.
1) 배열 순회 2) 문자열로서 비교
Todo 리스트는 배열의 순서가 달라질 수 있으므로 순서 변화를 인지하는 JSON.stringfy
가 가장 적절한 방식이라고 생각해서 문자열 비교 방식을 선택했다.
그외 트러블 슈팅은 팀 노션에 기록해뒀다.
회고
이번엔 소켓 오픈하고 데이터 주고받는 것에 온 집중을 쏟느라 블로그에는 일별 회고를 작성하지 않았다.
대신 팀 노션에!
끝으로 지속하면 좋을 것 / 문제였던 것 / 그 문제를 해결하고자 했던 시도들을 정리하며 간략하게 지난 2주를 돌아보려고 한다.
K
P
T
-
바로 적용하기 쉬운 자료들이 없을 뿐, 공식 문서는 있다. 물론 개념적인 설명 위주라서 쉽지 않았지만..
-
Next.js에서 redux-persist 설정하느라 힌디어로 강의하는 유튜브까지 봤다.
- 힌디어 하나도 모르는데 강의가 대략 이해된다니! 이게 바로 황무지를 개척할 때만 알 수 있는 즐거움인가..! 새하얀 눈밭에 첫번째 발자국을 남기는 기분이다. 🐾
덧붙이는 말
이번에도 무척이나 힘들고 고달팠지만 즐겁고 재밌었다.
개발은 평생 공부해야 한다는 말이 무섭게 들려서 예전엔 시작할 엄두를 못 냈었는데, 나는 나를 잘 몰랐던 모양이다. 성장 욕구 많고 배우는 것도 좋아하고 새로우면 궁금해하는 나에게 시도때도 없이 바뀌는 이 환경은.. 정말 완벽하다.
어제보다 오늘 더 낫고, 오늘보다 내일 더 나은 사람이 될 수 있단 게 참 좋다. 더 많이 배우고 더 많이 나눌 줄 아는 알맹이가 꽉찬 사람이 되고 싶다. 👏