원티드 프리 온보딩 1주차 과제 - 사전과제의 Best Practice

코몽·2023년 4월 29일
0

Wanted-Pre-Onboarding

목록 보기
2/4

원티드 프리 온보딩 1주차 과제 풀이 GitHub

개요

원티드 프리 온보딩에 합격했다.
2팀에 배정을 받았다.
사전과제가 리액트 처음 해보는 거였는데 어떻게 합격했지?

여튼 1주차 과제는 각자가 사전과제에서 제출했던 투두 리스트 중 각 부분에서
Best Practice라고 생각 되는 부분들을 모아 팀별로 동료학습을 통해
Best Practice Todolist 프로젝트를 하나씩 만들어 제출하는 것이다.

이하 Best-Practice는 통칭하여 BP라고 하겠다.
const BP = Best-Practice;

JS vs TS

type 사용시 오류 발생 가능성 저하 등을 이유로 사용하기로 결정

API 및 추상화**

내가 다른 팀원과 둘이서 맡은 부분으로 자주 사용되는
API 호출 부분을 추상화하는 역할을 맡았다.
fetch와 axios 중 코딩 편의성 위해 axios를 사용하기로 했다.

또한 기존에 클래스 형식으로 추상화 되있는 코드를 모던 리액트 스타일에 맞게
함수형으로 변환하고 객체를 리턴하는 방식으로 변경하였다(다른 코드와의 호환성 유지).

그 외에 객체 리터럴, HOC, hook 등 여러 방법이 있었지만 객체 리터럴은
너무 Vanilla st고 HOC는 클래스 컴포넌트 형식에 더 적합한 느낌에다
이미 Redirect 부분에 사용하기로 하여 여기까지 HOC 형태면
유지보수가 어려워 보여 패스했다.

또한 커스텀 hook의 경우 컴포넌트나 다른 hook 안에서 사용해야 한다는 점과
api 호출하는데 다른 hook 사용을 필요로 하는 로직이 없어 제외했다.

이번에 axios를 처음 써보게 되면서 공부하게 되었다.
axios instance를 사용해 BASE_URL을 정해놓으니 코드가 간결해져서 좋았다.

API를 작성하면서 에러 핸들링과 관련해 난관에 봉착했다.
사실 추상화 부분에서 모든 에러를 Http status code 별로 다르게 처리하고 싶었다.
그럴 경우 추상화하여 export한 함수 내에서 try catch로 잡아 alert해야 했다.
문제는 그렇게 하면 해당 함수를 import한 커스텀 hook 부분에서 에러를 감지하지 못해
에러 여부에 따라 다르게 동작하는 로직들을
추상화 함수 안으로 가져와야 했고 그러기엔 같이 따라와야하는 코드가 많아져
추상화 함수 내 코드가 번잡해질 것으로 판단하여 그냥 에러처리는
커스텀 hook 부분에서 처리하기로 했다.

상태관리*

사실 상태관리를 어떻게 할까 결정하면서 의견이 제일 많이 갈렸다.
ContextAPI를 사용하자는 쪽과 사용하지 말고 Props-drilling으로 하자는 쪽으로 나뉘었다.

ContextAPI 쪽은 이를 사용하면 코드 생산성 및 상태 관리의 용이함,
재사용성과 확장성 증가, Props-drilling 회피 가능 등을 예시로 들었고

Props-drilling 쪽은 투두 리스트 정도의 앱에
ContextAPI를 사용하는 것이 오버킬이고
props-drilling이라 해봤자 최대 2~3depth 정도 밖에 안돼
ContextAPI를 사용하지 말자는 것이었다.
추가로 Provider로 감싼 모든 자식들이 리렌더링 되는 것도 성능 적으로 안좋다는 의견도 있었다.

나는 이렇게 의견을 제시했다.
BP의 기준을 명확히 세우고 가야한다고 말이다.
우리가 현재 BP로 만들고 있는 이 프로젝트가
경량한 Todo-list에 알맞는 BP 기준으로 만드는 것인지
확장성과 재사용성, 기능 추가등을 고려하여
일반적인 프로젝트에 맞는 제너럴한 BP를 기준으로 삼아야 할지를 말이다.

왜냐하면 상태관리 이전에 논의 했던 다른 부분들에서는 오버킬이더라도
확장성, 재사용성, 중복 회피, 성능 등의 이유로 이걸 사용해보면
좋을 것 같다고 결론이 난 것들이 많은데, 상태관리 부분에 와서 갑자기
ContextAPI가 오버킬이라고 하니 뭔가 논리적으로 맞지 않아서였다.

다시 말하자면 Props-drilling를 쓰자는 쪽은 BP의 기준을
투두리스트 급의 작은 프로젝트에 알맞는 BP로 잡아야한다고 주장을 했는데
정작 다른 부분들에서는 확장성과 재사용성 등을 주장하며
제너럴한 BP를 쓰자고 주장하는 것이었다.

솔직히 말하면 매우 간단한 Todo-list 정도되는 프로젝트 기준에
lazy loading, axios, hoc, 추상화, styled-component,
debouncing, useCallback등의 최적화, 커스텀 hook 등 모든 것들이 다 OverKill이다.

Props-drilling이 2~3 depth 밖에 안되는데 전역 상태관리를 쓰는 것이
투 머치하다고 생각되면 api 호출하는게 몇 개 되지 않는데 추상화나
axios 같은 외부 라이브러리 말고 내장 fetch를 써야하고 소규모 프로젝트인
투두에 lazy loading이나 기존에 useEffect안에 한 줄로 처리 되던 리다이렉트를
코드 재사용성이나 코드관리 용이성 측면에서 HOC를
사용하자는 것들도 논리적 모순으로 다가왔다.
css도 추가로 설치가 필요한 styled-component가 아니라
그냥 Module 쓰는게 맞다고 생각한다.
그 것이 투두리스트의 규모에 알맞는 BP가 아닐까 생각한다.

사실 확장성/재사용성/관리용이성 vs 성능/코드량감소의 문제라 어느 쪽을 택하든
크게 상관은 없었지만 ContextAPI를 사용하지 말자는 쪽의 논리적 부조리가
개인적으로 마음에 안들었다.

그렇다한들 나는 사전과제가 첫 리액트고 ContextAPI를 한 번 밖에 사용해보지 않았고
심지어 나름 비효율적으로 사용했기에 딱히 반대 할 자격이 없다 생각하여
개인적인 의견 한 두 번 정도 피력하고 가만히 있었다.

결국 투표를 하였고 다른 부분들은 그대로 유지하고 상태관리 부분만 경량하게
props-drilling으로 가기로 했다.

물론 다른 팀들이 한 프로젝트가 BP는 아니지만 다른 팀 제출 코드를 보니
한 두팀 빼고 전부 props-drilling으로 한 거 보면 todo기준
BP가 맞았던 것 같다.
근데 그 팀들은 css도 module쓰고 다른 부분들도 다 경량하게...

그 외

Redirect 부분은 HOC로, css는 styled Component로,
추상화된 api를 커스텀 hook에서 호출한 뒤 component 등에서
훅을 다시 불러 사용하는 방식으로 작성하였다.

SignIn 페이지와 SignUp 페이지 UI가 거의 동일하고 텍스트랑 핸들러 정도만
바꿔줘도 돼서 하나의 Auth 컴포넌트로 합쳐서 중복을 줄이자는 의견을 제시했는데
Component 상으로 분리 되어있는게 맞다고 생각하는 의견들이 많아 분리하는 쪽으로 진행되었다.
이 부분은 어떤게 BP인지 잘 모르겠다.

개인적으로 매우 자잘한 부분들, if()로 할지 if () 로 할지 같은 띄어쓰기 문제,
if문에서 한 줄 일때 중괄호 생략 여부, 세미콜론, singlequote doublequote 문제,
arrowParens, type과 interface 중 어느 것을 쓸지 등 모든 부분을 세세하게 의논해서
코딩 스타일을 정하고 통일하고 싶었지만 첫 주에 다들 다른 일들과 관련해 바빴고
시간관계상 패스했다.

그래도 함수 선언식과 표현식, export import 방식 등을 의논하여 통일하게 되어 기뻤지만
함수는 표현식을 쓰기로 했는데 왜 계속 선언문을 사용하실까...

배운 점

DDD / axios / HOC / 추상화

위의 기술들이 이번 프로젝트를 통해 새로 배운 내용들이다.
적어도 우리 팀 프로젝트내에서는 그렇다.
그 외에 다른 팀들이 제출한 프로젝트는 아직 자세히 살펴보진 않았지만
나중에 일일히 다 살펴볼 예정이다.

  • DDD
    : 이번 1주차 과제와는 상관 없는 내용이지만
    사전과제에 DDD (Domain Driven Development)를 적용한 분이 계셨다.
    코드 보통 백엔드에 쓰이는 패턴이지만 요즘은 FE에도 종종 적용한다고 들었다.
    도메인 별로 코드를 나눠 응집도를 올리는 것 같다. (여기선 todo와 auth)
    추가로 이런식으로 나누셨다.

    presentation - view와 관련된 코드
    application - 전역 상태관리와 관련된 코드
    domain - type과 validation 함수
    infrastructure - api 관련 코드

    백엔드에 적용하는 방식을 살펴보면 복잡해 보이지만
    프론트에 쓰이니 조금 더 단순화된 것 같다.
    아니면 투두리스트라 그런 것 같기도...
    아직 DDD 패턴이 TS나 TDD처럼 필수적으로 자리잡은건 아닌 것 같아 시간관계상
    취업 후 필요하면 공부해 적용하는 연습을 해볼 예정이다.

  • Axios
    : Interceptor로 중간에 req와 res를 잡아 처리할 수 있어 좋아보였다.
    여기선 로컬스토리지를 처리할 때 사용했다. 나중에 처리할게 많아지면
    interceptor 코드가 길어질 수 도 있어 보인다.

  • HOC
    : Higher Order Component로 컴포넌트를 인수로 받아 로직을 처리하고
    그 컴포넌트에 props 값을 넣어 다시 반환하는 컴포넌트로
    추상화, 재사용성 증가 등에 사용될 수 있어 보인다.

  • 추상화
    : 자주 사용되는 로직을 함수로 따로 빼서
    가져다 쓸 수 있게 만들어 놓는데 응집도 높게 묶어서 추출한다.
    여기선 api 관련 로직들을 추상화 하였고 그 와중에 todo와 auth로 또 나누었다.
    추상화에는 class, js object, custom hook, HOC, function 방식 등
    여러개가 있고 모던 리액트 스타일에는 hook과 function 방식이 더 적합하다.
    HOC도 좋은 방식이지만 읽기가 상대적으로는 좀 더 까다롭다.
    여기선 function 방식으로 하되 return을 js object로 하여 export시
    호출을 해버려 import 하는 곳에서 따로 호출하지 않아도 사용 가능하게 했다.

profile
프론트엔드 웹 개발자

0개의 댓글