9개월 묵은 APPJAM 코드 뜯어내기 :: Recoil Selector Async Fetching

SOPT·2023년 1월 24일
0

web

목록 보기
7/7
post-thumbnail
post-custom-banner

🔗 이전 게시글 (Tistory)

(위 링크의 글을 보시면, 흐름 이해가 쉽습니다)

하나의 atom 상태를 가지고 컴포넌트마다의 커스텀 훅을 불러오려니, 중복적인 서버 통신이 일어난다.

Recoil 로써 캐싱을 할 방법은 없을지 알아보자.

Recoil Selector + Loadable

1. 효율적인 서버 통신

각 reviewId 에 맞는 책 정보 데이터를 비동기로 불러와 관리하고,

각 컴포넌트에서의 중복적인 데이터 패칭을 막기 위해 selectorFamily를 이용하였다.

이 때 selector는 캐싱 기능을 제공하며, 한번의 api call으로 처리할 수 있도록 도와준다.

Recoil은 📎 selector로 비동기 패칭을 지원한다.

구현 방법은 간단하니, 문서를 참고하면 좋을 것 같다.

Recoil 를 이용하여 비동기로 데이터를 패칭하는 여러 방법이 있다.

“fetch only one at the time, using a selectorFamily”

앞 포스팅에서 보였던 꼬리 질문/답변 기능은 “비동기로 패칭한 데이터를 기반한 전역 state”가 필요했다.

selectorFamily로 비동기 패칭을 구현하고, 이를 기반한 전역 state는 atom 으로써 동작하게끔 한다.

Recoil Selector

Selector 로 비동기 패칭이 완료된 데이터는 Atom 에 업데이트 한다.

이와 같은 구조로 설계함으로써 아래와 같이 수많은 중복 통신을 방지할 수 있었다.

Before (중복 통신)

->

After (Selector Async Fetching)

2. Suspense 처리?

⛔️

Recoil 은 Facebook에서 만들어진 라이브러리로, Suspense와의 호환성이 좋다.

하지만 작업을 하다보니

Next app 을 build 할 때, static page 를 생성할 때에 계속해서 timeout이 발생해 build가 되지 않는 이슈가 발생하기도 한다 (static-page-generation-timeout)

찾아보니, Next 에서 Recoil의 selector 와 Suspense 를 함께 사용할 수 없는 📎 이슈가 있었다.



왜 그럴까?

RQ, SWR과 같은 패칭 라이브러리는 fetch-on-render 의 방식으로,

컴포넌트 렌더링 이후에 네트워크 요청을 한다.

React18의 Suspense 기능은 render as you fetch 을 지원하는데,

네트워크 요청을 하고 컴포넌트 렌더링을 이뤄지도록 한다. 이 때, 데이터가 다 불러와짐(stale data)을 가정하고 fallback으로 넘겨준다.

에러 대신 Promise를 throw 하는 것을 Suspense가 감지할 수 있게 된다.

이를 이용해 Recoil async selector는 Promise를 throw 하여 Suspense를 지원하도록 하지만,

Next app의 SSR에서는 데이터 패칭이 끝나지 않아 timeout 이 일어나는 게 아닐까 하는 📎 의견이 있다.



이를 해결하기 위해 Recoil은 fetch-on-render 방식의 Loadable을 지원한다.

(아쉽지만 로딩처리에 대한 로직 구현을 Suspense 로의 추상화는 다음 과제로 남겨놓고,)

📎 useRecoilValueLoadable 훅으로 세가지 상태에 대한 예외 처리를 해주자. (이 역시 공식문서의 예제가 잘 나와있기에, 설명을 대신 해주리라 생각해요)

useRecoilValueLoadable 훅은 Suspense를 위해 비동기로 값을 읽어올 때 Error 혹은 Promise를 던지지 않고, “Loadable” 객체를 리턴한다.

hasValue, loading, hasError 3가지 상태의 Loadable 객체로써 컴포넌트를 분기 처리하여 나타낸다.

Next app Build

📎 Build 까지 완료 🔐

글을 줄이며

하여,

Recoil 을 활용해 atomic 한 전역적인 상태를 관리할 수 있었고,

해당 페이지에 대해 중복되는 서버통신을 캐싱하여 막아주었다

설계 양, 사용법이 다소 간단한 Recoil 을 사용하여 작업 시간이 그렇게 길지는 않았지만, 사용할 수록 아쉬운 부분들도 많았다

특히, 서버 사이드 데이터 관련한 기능이 react-query, swr에 비교도 안 될만큼 부족하고,

데이터 갱신과 같이 불안정한 기능들이 많다.. 📎 수많은 ISSUE들이 대기 중이다

그러나 간단하게 전역으로 상태를 관리하고, 로직을 효율적으로 설계하여 관리하기에는 굉장히 편리하였기에, 서비스에 맞게끔 맞는 기술을 사용하면 좋겠다.

북스테어즈는 이 작업을 시발점으로 다시금 작업을 시작하게 되었다.

개발을 처음 접하던 우리는 기본기에 충실하며 라이브러리를 최소화하는 개발을 하였다.

심지어 객체의 깊은 복사, Debounce, Unmount Animation 모두 직접 구현하였다.

그리고 지금, 로딩 및 에러처리나, 반응형 작업이나, 부분부분의 리팩토링, … 뜯어낼 구석이 많지만 :( …~

오히려 이 과정이 개념을 더 깊게 와닿게 해주었고 더 멀리 나아갈 수 있다는 자신감을 주었다.

이 모두가 팀원들에게 성장의 발판이 되기를 바란다.


🔗 해당 게시글 보러가기 (Tistory)

작성자 :: IN SOPT 웹파트장 이주함

profile
IT 대학생벤처창업동아리 SOPT의 공식 블로그입니다.
post-custom-banner

0개의 댓글