React Native, Apollo Client와 상태관리

Soen·2022년 3월 6일
0

React-Native

목록 보기
3/3
post-thumbnail

2021년 10월에 썼던 글입니다.

플러터 사용할 때에도, 처음 RN을 다룰 때에도 항상 문제였던 건 스크린끼리 데이터를 매개변수로 주고 받는 것이었다.

🤮 나름 대규모 프로젝트로 처음 했었던 플러터 앱의 경우에는 2-4 Depth가 있는 페이지에 필요한 데이터를 최초 메인 스크린에서 불러오니까, 데이터가 길고 긴 터널 (=각종 스크린) 들을 거쳐서, 거쳐서 필요로 하는 페이지에 도달하곤 했다. 수동으로 다 만들어줘야 했던 체이닝의 노력은 둘째치고, 중간에 체인 이름이라고 달라지기라도 하면 지옥이 따로 없었다.

Apollo, GQL은 서버 개발자와 같이 개발한 적이 없어서 항상 프론트에서 모든 걸 처리하는 토이 프로젝트만 했던 나에게 너무 큰 벽이었다. 데이터를 불러오고, 캐시에 저장하고.. 항상 그래왔듯이 토이 프로젝트였으면 대충 프론트엔드에서 알아서 처리하도록 치웠을 것이다. → 성장은 강제성에서 비롯되나봐요.

사실 공식 문서 읽으면 아마도 쉽게 터득할 수 있었겠지만 영어 읽기가 귀찮아서 몸으로 체득했던 GQL의 어썸한 부분을 정리해보려고 한다.


ReFetch?

데이터를 주고 받는 앱을 처음 만들고 나서, 처음 마주친 문제는 ReFetch 였다.

예를 들면, 메신저 프로그램에서 친구 목록에 떠 있는 읽지 않은 메세지를 읽고 나서 (→ 채팅방 스크린으로 넘어 왔다가) 다시 친구 목록 스크린으로 왔을 때, 우리 입장에서야 당연히 친구 목록에 떠 있던 읽지 않은 메세지 표시가 사라져야 할 것 아닌가.

하지만 시키는 것만 철저히 하는 앱 입장에서 보기엔, 친구 목록 스크린에 진입 (Navigation Stack에 친구 목록 스크린을 PUSH)하면서 서버에 있는 데이터를 Fetch 해 왔고, 채팅방에 진입하면서 (Navigation Stack에 채팅방 스크린을 PUSH) 채팅 메세지를 읽었음을 서버에 전송했고, 뒤로 가기를 하면서 (Navigation Stack에서 채팅방 스크린을 POP), 친구 목록 스크린으로 진입이 되고, 따라서 친구 목록 스크린은 데이터를 다시 업데이트하라는 명령을 받은 적이 없게 된다..!

그렇다면 가장 간단한 방법은 친구 목록 스크린이 다시 데이터를 불러오면 된다. → 여기서 파생되는 문제점은, 스크린이 사라졌는지, 어디서 왔는지를 제어하는 게 오히려 더 복잡하다는 거다.

여기서 Apollo-GQL은 어썸한 방법을 사용하는데, GQL의 뮤테이션(Create, Update, Delete) 전송할 때, 서버가 반환해주는 값을 사용하는 것이다. 어차피 모든 데이터는 id를 가지고 성능을 위해서 Cache에 저장하게 되니까, 반환하는 이 id 값을 가지고 State를 쓰는 것처럼 알아서 Apollo가 같은 값을 사용하는 친구들을 바로 다 업데이트해준다!

🥲 이렇게 어썸한 방법을 사용하는지 모르고, 난 뮤테이션이 왜 값을 반환하는지 궁금해했었다. → 값이 잘 바뀌었다는 확신..? 그런건가 싶었음.

요런 개념을 이용하면 로딩을 더 빠르게 할 수 있는 방법도 존재한다.

Fetch-policy : Cache-only & Cache-network

어차피 Cache에서 Apollo가 데이터를 불러온다는 점을 활용하면, 각 스크린에서 데이터를 불러오는 속도를 더 빠르게 할 수도 있다. Cache-Only를 통해서 먼저 데이터를 보여주고, 이후에 Cache-Network를 사용해서 최초 데이터는 캐시를 통해서 보여주고 → 이후에 데이터를 한번 더 서버에 요청해서 새로고침을 하는 스타일로 코드를 작성하면 된다.

💡 앱의 스크린을 설계할 때, 어디서 네트워크 요청이 필요한지 확실히 잡는 것도 앱의 사용성을 높이는데 큰 도움이 될 거 같다. 코드 작성은 큰 차이가 없더라도.


나중에 알고 보니, 이게 상태관리 라이브러리의 의의였다.
체이닝이라고 써뒀던 부분이 '상태 끌어올리기(Lifting State Up)' + 'props drilling' 문제였다.
이걸 해결하기 위한 방법이 Context 였고.

Apollo는 자체적으로 캐시에 값을 저장하고, 이를 Cache-only Policy를 통해서 불러올 수 있다.
Redux 등의 상태관리 라이브러리를 사용하지 않고도 네트워크 통신을 위해 필요하는 Apollo의 Cache를 상태관리 라이브러리처럼 사용할 수도 있을 것 같다.

참고

🔗 리액트 상태관리 1부 Velog:
https://velog.io/@longroadhome/FE-리액트-상태관리-1부
🔗 Apollo Client는 Redux와 무엇이 다른가
https://d2.naver.com/helloworld/4245995

0개의 댓글