React-Express Velog Clone Renewal (with redux & redux-thunk)

大 炫 ·2021년 6월 28일
0

Velog Clone

목록 보기
8/8
post-thumbnail

배포 : http://hyeon4137.shop/
코드 : https://github.com/DanHumphry/Velog_Refactoring
로그인 데모 ID : demo@naver.com
로그인 데모 PW : test123123

🚨 주의 : 해당 포스트는 해당 시리즈의 과거 코드와 최근 코드를 비교합니다.

production 코드가 아닌 development 코드입니다.

Skill

Frontend

  • React
  • Typescript , Redux , Redux-Thunk , React-Router-Dom

Backend

  • Express
  • Sequelize , Passport

DevOps

  • AWS EC2 , Route 53
  • MySQL

리뉴얼하며

무엇이 바뀌었나 ?

과거 axios및 fetch, CORS, 상태관리, hooks에 관한 내용 모두 무지할때
CORS를 허용하고 response객체를 backend로부터 받는데까지 며칠을 고생했다 :(

그렇게 대가리를 박으면서 React + DRF를 이용해서 velog를 따라만들었는데 어찌어찌 기능은 조금씩 추가하더라도
코드개선이 막막했는데 용기내어 모듈화상태관리에 중점을 둔 리팩터링을 해보기로 했다.
되는데로 기능만 늘렸던 코드와 개선된 코드를 비교하며 어떻게 바뀌었는지 살펴보자.

폴더구조

왜 이렇게 차이가 많이 나나 ?

  1. 상태관리
    폴더구조는 늘린다고 능사가 아니지만 과거에는 간단해도 너무 간단했다..
    모든 state값들을 props로 넘겨서 주고받다보니 폴더구조가 복잡해질수록
    state값들을 주고받기 어려우니 자연스럽게 하나 하나의 js파일이 점점 무거워지는 나쁜코드가 되버린 것이다. (700줄이 넘는 코드도 있ㅇ..)
    redux를 사용하게되니 store에서 필요한 state값을 꺼내어 쓸 수 있게되니
    당연하게도 컴포넌트를 쪼개는데 부담을 느끼지 않을 수 있었다.

  2. 모듈화
    재사용하기 쉬운 axios라던지 hooks라던지 충분히 모듈화를 할 수 있는 껀덕지가 많이 있음에도 그걸 캐치할 능력모듈화를 할 능력도 없던시절이었다.

학원에서의 가르침도 받은 적 없고 강의도 짧게 듣고는 '당장 할 수 있는것'에 집중했던 '오만''패기' 에서는 당신도 배울 수 있는것이 존재한다.
"Worst of Worst"

코드비교

인라인 함수 (잘못된 예시)

잘못본거 아니고 과장된것도 아니다.
인라인 함수가 무조건적으로 잘못됬다는 얘기는 아니지만,
이런식의 함수작성은 무조건적으로 잘못됬다는 얘기는 맞다.
onChage핸들러도
오히려 이렇게 작성할 바에 인라인으로 작성해라는 의견도 있을정도니까..

여하튼 비동기처리를 위한 fetch를 사용할때
request로 보낼 데이터를 처리하는 함수에서 hooks를 이용하고,
response로 받는 데이터를 setState하는 과정에서 redux를 이용해서
어떻게 달라질 수 있었을까 ?

hooks (좋은 예시 1)

hooks/useInput.ts

(출저 : 인프런 조현영님의 React NodeBird 또는 Slack Clone)

많은 도움이 됬던 분인데 앞으로 강의를 참고한 내용들은 어지간하면 포스팅에 올리지 않을 생각이니 시간적 여유가 있다면 강의를 보는것도 추천한다 !

useInput은 크게
value : initialValue ,
handler : value의 onChage handler ,
setValue : value를 초기화같은 직접적으로 setStateAction해야할 때 쓰일 setState ,

위와같은 useInput은 원한다면 input, textarea들이 쓰이는 어디에서나 import해서 사용할 수 있다 !

그 예로

import한 useInput은 위의 모습처럼 사용할 수 있고
또 아래와 같이 사용된다.

모듈화 (좋은 예시 2)

위 사진의 submit함수에서 최종적으로 실행되는 함수인 dispatch함수는
redux-thunk라는 미들웨어를 사용함으로써 thunk로 이어지게된다.

thunks/user.ts

redux의 dispatch는 action에 따라 store에 있는 값들을 변경시키는데
thunk라는 미들웨어는사이를 비집고 들어가 무엇을 하려고 하는걸까 ?

상황을 악화시키기위해 나쁜예시의 코드로 다시 돌아가보자.

그곳의 인라인 함수안에서 fetch가 진행되는 동안 보여줄 loader가 존재하는데
loader를 활성화하기 위해
1. fetch함수가 일어나기전 loader활성화를 위한 state을 변경시킬 액션 dispatch

2-1. fetch 실행 후 fetch의 응답이 올바를 때

  • 받은 응답으로 state를 업데이트 시킬 액션을 다시 실행
  • state가 업데이트 된 후 loader의 비활성화를 위한 액션 dispatch

2-2. fetch 실행 후 fetch의 응답이 올바르지 않을 때

  • loader의 비활성화를 위한 액션 dispatch
  • 받은 에러를 출력

사실 위와같은 상황은 객관적으로 간단한 예시라고 생각하는데
위의 상황에서 액션을 취소시켜야하는 상황, 또는 실패해도 다시 재요청을 해야하는 상황, 딜레이를 줘야하는 상황, 등 이를 미들웨어 없이 직접 구현해야한다고 상상해보자.

결국엔 내가원하는 상황이 복잡해졌을 때 thunk나 saga같은
미들웨어가 진정 빛을 발한다고 생각한다.

모듈화로 다시 돌아가보면
redux는 아래 3장의 사진과같이 코드의 양은 비교적 많을 수 있다.

api/user.ts

actions/user.ts

reducers/user.ts

하지만 척척척 조립하는 방식으로 작성되는 패턴들은
금방 익숙해지며 코드리뷰를 하거나 코드 수정이 필요할때
패턴이 없는 코드보다는 대부분의 경우 좋을 것이라고 말할 수 있다.

그 외에도 비교점이 엄청엄청 많지만 이제 정말정말 취업해 볼 생각이라
면접준비 라던지,, 사전과제 라던지,,
취뽀를 성공적으로 마치고 또 리뉴얼로 돌아오면서 아쉬움을 달래보려고한다.

마치며 아쉬웠던 점

금방 끝날 줄 알았던 리뉴얼이 디테일한 부분에서 "조금만 더.. 조금만 더 .."
하다보니 자꾸 길어지게 되더라.
그럼에도 자꾸 돌아보게 만들었던 요소들이 있는데

프론트엔드에서

graphql, sass, saga, immer와 더불어
csr으로 작성된 코드를 nextJS와 함께 ssr으로 바꾸며
검색엔진에 노출 시켜 보고싶고
bundle-analyzer를 통해 build용량을 줄여보고 싶었다.

백엔드에서

제일 말썽은 단연 Sequelize라고 자신있게 말할 수 있다.
erd를 따로 만들지도 않고 메모장에 적어 하는것도 아니었던 막무가내식은
진즉에 버렸어야했다.
사실 백엔드는 이것저것 엉망이라 docker를 제외하고는 (ec2를 몇 번 갈아엎다보니..)
새로운 기술을 배워 적용시키는 것 보다 기존것들을 좀 더 딥하게 공부해 보려고 한다.

profile
대현

0개의 댓글