소프트웨어 엔지니어링/프론트 엔드

[원티드1월챌린지] FE 프리온보딩(React-Query) 종료후 과제 보충

dhsimpson 2023. 1. 25. 01:08

1. react-query 의 isLoading, error 를 Suspense 및 ErrorBoundary 로 대체했다. (좀더 선언적이며 JSX/TSX 친화적이게)

[commit link]

 

a. 우선 react-query client 에 'suspense' 를 사용한다고 {suspense: true} option을 줘야 한다.

b. react-query의 useQuery 훅이 반환하는 isLoading,error 를 각각 suspense, errorBoundary 로 대체한다.

빨간색 표시 : isLoading -> suspense (참고 :  Suspense with React-Query 사용법)

보라색 표시 : error -> ErrorBoundary

c. ErrorBoundary 는 아직까진 React 내장 컴포넌트로 지원하진 않아 직접 정의해줘야 하는 듯 보인다.

(참고 : ErrorBoundary 컴포넌트 만들기)

d. updateTodo, showTodo 컴포넌트는 데이터가 로딩된 이후에 import, 렌더링 돼도 되므로 lazy 로딩을 이용해 code split 했다.

 

2. react-query 옵션에 cache 및 stale time 적용

cacheTime 및 staleTime 을 각각 2, 5 초 로 설정했다.

a. 첫 데이터 fetch 후 2초 까지는 캐시 된 데이터를 사용하며,

b. 2초~5초 까지는 캐시 된 데이터를 사용하지만 미리 새로 데이터를 fetch 하고

c. 5초가 지난 이후엔 새로 fetch 했던 데이터를 사용한다. (b 시간에 화면에 action 을 취하지 않았다면 b 는 제외 된다.)

3. 관심사의 분리 (todo update, delete 관련 비즈니스 로직을 ui 로직에서 분리)

[commit link]

DeleteTodoButton.tsx 엔 삭제기능(모달 컨트롤, 삭제 로직) 관련 비즈니스 로직이 있다.

이를 useDeleteTodo 라는 hook을 생성해 해당 hook 에서 비즈니스 로직을 관리하도록 리펙터링 했다.

또한, 기존의 useTodo hook 에 필요한 매개변수 중 함수가 대다수라 가독성을 많이 해쳤는데,

이 또한 createUseTodoParams.ts 에서 util 함수를 만들어 관리하도록 했다. (input param 을 생성하는 것에 대한 관심사의 분리)

기존의 로직 : useTodo 에 전달인자 를 inpu하는 코드가 너무 길어 가독성을 해침
[link]
해당 input 하는 함수들을 변수 형태로 return 받아 사용
[link]
파라미터를 생성하는 함수 useDeleteTodoParams
[link]
 
 

(c.f. update 로직도 같은 방법으로 관심사의 분리를 했다.)

 

4. 에러 처리(todoDetail 400 에러에 대한 처리)

todoDetail (url : /todos/[:id]) 에 진입 시 서버에 없는 id값을 path param으로 전달하면

서버에서 400 에러를 response 해 준다.

해당 에러가 ErrorBoundary 에서 catch 되면 fallback 컴포넌트에서 Retry 버튼을 보여주는 대신, 뒤로가기를 해준다.

(todo detail 정보를 불러올 수 없다면 아예 해당 화면으로 진입하지 못 하는게 맞다고 판단)

 

c.f.) 기존엔 401(인증 토큰 에러) 에 대한 처리만 하고 있었으며, 로그인 화면으로 이동시킨다.

 

5. 400, 401 이외의 에러가 발생하는 경우 Retry 버튼을 클릭해 다시 쿼리할 수 있도록 해준다.

동영상 예시에선 랜덤하게 axios timeout 이 발생하도록 했다.

에러가 발생했을 때, fallback 컴포넌트로 Retry 버튼을 넣어줬다.

 

[timeout 발생 시 retry 버튼 클릭]

 

[c.f. timeout 발생 시 다른 todo id로 접근]

 

7. react-hook-form 적용

[link]

 

[register]

<TextField> 의 name 은 register 로 대체했다.

이 코드에서 useForm hook 의 register 는 코드에 큰 변화를 안 줬지만,

 

[handleSubmit]

handleSubmit 은 큰 변화를 줬다.

그럴 수 밖에 없는 게, form data 에서 가장 로직이 복잡하고 많은 부분이

 

  1. form data 를 가져오고
  2. 해당 데이터를 state 에 저장하고 (생략 가능하지만, 컴포넌트 계층을 나누는 등의 상황에 따라 필요해진다.)
  3. 데이터를 이용해 서버에 쿼리하기

의 세 단계이다.

 

지금까지의 경험으로는, 본래 1,2,3 이 하나의 컴포넌트 혹은 scope 에서 실행 되지만

컴포넌트 계층화/ 관심사 분리 등의 이슈로 1,2,3 이 나눠 지는 것 같다.

 

handleSubmit 은 1,2,3 을 다시금 하나로 묶어주는 역할을 하는 것 같다.

 

10 라인이 삭제되고 4 라인이 추가됐다. 총 6 라인을 줄이게 된 셈이다.

 

[인프랩 랠릿 팀의 포스팅] 에선 굉장히 많은 코드 라인을 줄일 수 있던 것으로 보아 그 외의 다양한 이슈도 해결해 준 것으로 보인다.

(에러 컨트롤 로직이라던가..?)

8. [추가 학습해 볼 것] useQueryErrorResetBoundary

react-query 에서 reset 관련한 useQueryErrorResetBoundary 훅을 제공하는 듯 한데, 학습 후 이 포스트에 추가