- 공동 작업을 위한 코드 포멧 통일을 위해 적용
- 서버와의 통신을 위해 axios를 사용
- 서버와의 통신 자체를 관리하고 통신 결과에 따른 처리를 하기 위해 React-Query를 사용
- 통신 데이터를 포함해 전체적으로 관리되는 전역 관리 데이터를 사용하기 위해 Recoil을 사용
- 기존에 전역 상태 관리로는 Redux를 고려했지만, 보일러 플레이트와 Redux를 쉽게 사용하기 위해 Redux-Toolkit을 도입 하는 등... 복잡한 구성 대신, 전역 관리는 좀더 단순한 Recoil을 사용하고, 통신 관리는 React-query로 분리해서 사용
- 서버에서 전송되는 JWT 토큰에 payload 내용을 decode시켜 유효 여부, 만료 여부, 사용자 정보 조회 등의 목적을 위해 활용
- 경고창, 알림창 등의 기능을 좀 더 사용자 친화적인 디자인을 적용시키기 위해 사용
- 알림을 위해 좀더 단순한 react-toastify를 고려했지만 좀더 전체적인 조화를 위해 sweetalert2를 적용함
- 추후 단순 상태 알림을 진행할 경우 sweetalert2와 함께 react-toastify를 고려
- 각 컴포넌트 단위로 속성값에 따라 동작하는 과정을 확인하고 학습을 위해 도입
- 초기 설정 시 버튼, Input 등의 최소 컴포넌트에 적용 후 기본적인 방식을 인힌 뒤, 실제 개발에서는 시간 부족으로 인해 활용하진 못함
- 패턴에 익숙해지기 위해 굉장히 작은 단위부터 쪼개서 구성을 했다. 그러나 작은 프로젝트여서 그런지 아토믹 구조의 장점인 재사용성이 크게 느껴지진 않았다. 오히려 너무 잦은 컴포넌트 렌더링과 props dilling에 문제점이 생겼다.
- 좋아요 기능이 들어있는 곳에 console.log()를 찍으면 좋아요 할때마다 4번씩 찍히고 있다. 좋아요 요청을 mutation하고, 그 바뀐 db데이터를 다시 page->template->molcules->organism에 적용하기 때문에 발생하는 것으로 생각된다. 이 문제를 해결하려면 usememo로 pure component화를 시키면 괜찮다고 하지만 이는 남용하지 않고 복잡한 로직이 들어있는 컴포넌트에만 사용을 해야한다고 한다. 그럼 클릭 한번에 4번이나 재 렌더 되고있는 이 컴포넌트, 정말 이대로 두어도 괜찮을까? -> 해결 : 좋아요 컴포넌트는 문제가 없었음. 정리하자면 1. useQuery로 받아온 data를 recoil에 넣어서 컴포넌트에게 전달한 문제로, 좋아요 버튼을 누를 경우 누르지 않은 다른 컴포넌트까지 리렌더링 되고있던 문제 2. useQuery가 다른 의존성 패키지들과 충돌하여 react strictmode일때 두번 렌더링 되는 부분에서 문제를 일으킨 다는 듯? 어떤 패키지와 문제를 일으키는지는 파악 불가. 해당 이슈 벨로그에 정리 https://velog.io/@hi4656/useQuery-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4-2%EB%B2%88-%EC%94%A9-%EC%9D%BC%EC%96%B4%EB%82%98%EB%8A%94-%EB%AC%B8%EC%A0%9C
- mutation으로 delete 요청을 보내는 삭제버튼이 useCallBack으로 감싸주지 않자 무한삭제가 발생했다. onClick에 넣어준 함수가 리렌더링이 되면서 왜 자동실행되는지 이유를 모르겠다.
- 재사용성이 높은 컴포넌트만 아토믹하게 만들고 나머지는 유도리있게 organisms이나 template에서 구성해도 괜찮지 않을까 생각이 들었다. 어디까지 디자인패턴을 적용시켜야 할지 고민이 되었다.
- 아직 타입스크립트 구조에 익숙하지 않아서 인지 사용에 오히려 불편함을 느낀다.
- 데이터를 전달할때 object 끼리의 연결에서 type 에러가 종종일어난다.
- 눈가리고 아웅 하는 형식으로 중간에 any를 두고서 데이터를 전달하는 경우도 생겼다. 자유로운 스크립트 환경에서 규제와 같은 타입이 적용되니 익숙하지 않아서 발생하는 문제 같다.
- 좀더 익숙해 지면, 코드의 생산성이나 구성이 좀더 깔끔해 질 것 같다.
- 도입은 서로간의 코드 스타일 통일을 하고, 효율적인 코드 구조 도입을 위해서였지만, 처음 접해보는 수많은 에러에 오히려 시간을 많이 뺏긴것 같다.
- 사소한 것부터 중대한 사항까지 전부 오류로 덮어버리는 탓에 나중에는 점점 오류에 대해서 무뎌지는 듯 기분이 들었다.
- 중간에는 쓸데없는 오류가 발생하면 그냥 규칙으로 들어가서 비활성화를 해버리는 경우도 생겼다.
- 후반에는 조금씩 오류 구성에 맞춰서 해석을 하고 구성을 맞춰보려 노력을 했다. 처음에 익숙하지 못해 방황하는 시간으로 긴 개발의 시간을 보내고, 점점 익숙해 진다면 나중에는 코드를 작성하는 스타일이나 구조를 조금씩 효율적으로 짜게 되지 않을까 생각이 든다.
- 서로 처음으로 합을 맞춰보기에 처음에는 기능을 달리해서 개발을 진행했다. 회원관련 기능(로그인, 회원가입) 포스트관련 기능(포스트 표시, 삭제 등...)으로 나눠서 개발을 진행했다.
- 처음에는 각자가 별도의 파트를 작업하기에 접점이 없었지만, 점점 공통 기능으로 나아가고 곂치는 부분이 생기자 조금씩 문제가 생기기 시작했다.
- 서로가 작성한 코드가 곂쳐서 충돌이 일어나 각자 소스코드를 하나씩 확인해 가며 해결을 하거나, 공통용으로 작성한 권한 관리, 헤더 등에서 문제가 생겨 다른 작업 파트에 영향을 주기도 했다.
- 서로 개발이 지체되는 상황에 서로를 격려하고 소통하며 이슈는 잘 해결되었지만, 혼자만의 코딩이 아닌 협업에서 자신의 결과물이 상대방에게 영향을 미치면, 그 상대방은 내 코드에 대해 모르기 때문에 큰 장애물로 다가올 수 있다고 생각이 들었다.
- 협업을 하면서 누군가와 다른 기능을 개발해도, 서로에게 맞춰고 서로가 이해할 수 있도록 소통을 하며, 중요한 점은 내 코드에 대한 책임을 져야한다는 것을 느꼇다.
- 추가로 리액트와 스프링으로써 대화를 할때 서로에게 당연한 것을 상대방은 모를 수 있다는 것을 느꼈다. 서로 다른 파트를 제작한다고 같은 파트끼리 이야기를 나눌 것이 아니라, 만약 상대방이 알아야 할 것 같다고 느끼는 사항은 자료를 제작하는 한이 있더라도 쉽게 상대방에게 접근해 소통이 필요한 것 같다.
- 처음 API를 기획하면서 우리는 단순하게 생각 나는대로 기본적인 컬럼을 넣고 상세한 규칙까지는 정하지 않았다.
- 후반부 까지 가면서 느꼇던 점은 Spring과 React의 소통은 API로 이루어진다는 점이다.
- 모든 개발이 API로 중심이 되어가지만, 만약 API가 React나 Spring의 관점으로 이루어지지 않고 상상으로만 이루어진다면, 결국 우리는 상상속에 서버나 클라이언트와 연결을 시도하게 된다는 점이다.
- API는 기능을 개발할 때마다 새롭게 바뀌었으며, 그때마다 API에 대한 논의를 다시 해야했다. 누군가는 API를 따라오지 못했고, 누군가는 서로의 API와 기능이 매치가 안되는 등 초반에 제대로 기획하지 못한 API는 후반에 와서 더욱 크게 느껴졌다.
- 기획은 처음으로 끝나는 것이 아닌 모든 과정을 통틀어서 영향을 미치고 가장 중요한 점이라고 생각이 든다.
- FormData에서는 int를 String으로 변화해 처리한다. 잘 모르는 라이브러리는 우리가 애써 고민한 구성과 인터페이스 type에 담긴 int하나가 기능을 멈춰버리는 오류로 바뀌었다
- 이 말에서 중요한 점은 때로 열심히 만들고 구성한 기능은 라이브러리 하나때문에 방향을 틀어야 할때가 있다는 점이다.
- 라이브러리는 편리하지만, 그 구성과 기능을 이해하지 않고 가져다쓰면 문제가 생기고, 문제에 도달했을때 어떻게 처리할지 고민하는데 긴 시간을 쓰게 만든다는 것이다.
- 실제로 프로젝트를 구성하면서 가장 아쉬운 점은 오류와 테스트다
- 바쁜 과정에서 기능 개발하는데 초점을 맞추느라 놓쳐버린 테스트와 그로인해 발생한 오류가 많다.
- 지금도 로그인에서는 엔터키에 대한 동작이 제대로 되지 않는다.
- 리액트 Hook에서 useForm을 사용하면 엔터에 대한 커밋이 자동 적용되는데, 필요하다고 만든 유효성 검증 부분과 충돌이 나고 useState를 활용한 이벤트 관리에서 submit에 대한 충돌이 발생하기 때문이다.
- 몇시간에 걸쳐 고민하고 라이브러리 API 공식 문서를 확인해가면서 결국 투자되는 시간이 아까워 포기를 결정하고 말았다.
- 바꾸지 못한 결과와 투자된 시간이 조금 아쉽긴 하지만 교훈으로 삼고자 한다.
- state는 server state와 client state로 구분할 수 있다.
- server state는 서버로부터 불러오는 데이터로 비동기적 상태를 가진다.
- client state는 클라이언트가 제어, 소유하는 데이터로 동기적인 상태를 가진다.
- 우리가 집중해야할 부분은 client state인것 같다.
- 리액트에서 state는 대부분 전역적으로 관리가 된다. state는 원하든 원치 않든 렌더링에 영항을 미친다.
- 영향을 미친다는 말은 즉, 우리가 state를 남발하면 페이지는 수없이 렌더링을 반복할 것이고, state를 관리하지 못한다면 그만큼 낭비되는 성능도 많을 것이란 뜻이다.
- 프로젝트를 진행하면서 state를 컴포넌트 곳곳에 사용하며 state가 마치 onClick 할때 데이터 연동할때 쓴다 처럼 성능에 대한 깊은 관심없이 남발을 한 경우가 있었던 것 같다.
- 남발된 state는 결국 event를 꼬아 버리고 저장해둔 데이터를 초기화하거나 원치않는 기능을 호출하는 등 잘못된 구성을 초래하는 것 같다.
- state는 단순한 변수 저장공간이 아닌 렌더링과 연결된 것을 염두에 둬야할 것 같다.
├── components # 재사용을 위한 작은 단위의 컴포넌트
│ ├── atoms # atoms 컴포넌트
│ │ ├── Buttons
│ │ ├── NavButton
│ │ ├── LikeButton
│ │ ├── Input
│ │ ├── Figure
│ │ ├── Title
│ │ ├── Text
│ │ └── TextArea
│ ├── molecules # molecules 컴포넌트
│ │ ├── PostTopBar
│ │ ├── LoginForm
│ │ ├── RegisterForm
│ │ ├── PostLikeInfo
│ │ ├── userName
│ │ ├── userThumb
│ │ ├── postContent
│ │ ├── Navigation
│ │ └── AddImgInput
│ └── organisms # organisms 컴포넌트
│ │ ├── LoginContainer
│ │ ├── RegisterContainer
│ │ ├── Header
│ │ ├── Post
│ │ └── WriteForm
└── templates # 컴포넌트들 합치기
│ ├── LoginTemplate
│ ├── RegisterTemplate
│ ├── ListTemplate
│ └── WriteTemplate
└── pages # 기능 완성
├── Login
├── Register
├── List
├── Write
└── Mypage