시작하며...
우주윗미 프로젝트에서 TanStack Query의 옵티미스틱 업데이트를 사용해서 게시물의 좋아요 기능을 구현하였다.
그런데 오늘 useState로 구현할 수 있을 거 같은데 굳이 TanStack Query를 사용한 이유를 질문받았다.....!
(약간 당황하면서 대충 서버 상태를 반영해 준다고 답을 했다.)
그래서 이에 대해 다시 한 번 생각해 보면서 글로 정리하게 되었다.
왜 useState가 아닌 TanStack Query를 사용했는지!!
(참고로 TanStack Query의 옵티미스틱 업데이트를 적용한 내용은 해당 블로그 글에서 확인할 수 있다.)
1. 데이터 관리 관점
데이터 관리 관점에서 useState와 TanStack Query를 비교해 보았다.
1-1. useState의 데이터 관리 관점
useState 장점
별도의 라이브러리 없이 React 자체로 관리를 할 수 있다.
useState 단점
useState로 상태를 바꾼다면 그 값은 해당 컴포넌트 내에서만 영향을 미친다.
해당 프로젝트는 좋아요를 표시하는 곳이 2곳에 있고, 이들의 컴포넌트는 서로 다르다.
그래서 여러 컴포넌트가 동일한 데이터를 공유하는 경우, 전역 상태를 관리하는데 어려움이 있다.
(전역 상태 라이브러리를 사용할 수 있지만 useState를 사용하는 장점이 사라짐)
또한 useState는 클라이언트 측 상태이기 때문에 서버와 동기화하지 않으면, 서버로부터 갱신된 데이터를 수동으로 가져와야 한다.
그래서 로컬 상태와 서버 상태 간의 불일치가 발생할 수 있게 된다.
⇒ 전역 상태 관리 어려움, 서버 상태와 동기화 문제
1-2. TanStack Query의 데이터 관리 관점
TanStack Query 장점
서버에서 가져온 데이터를 캐싱하여 여러 컴포넌트에서 같은 데이터를 참조할 수 있게 된다.
그래서 서버 상태와 클라이언트 상태 간의 동기화를 효율적으로 관리할 수 있게 되어, 위에 사진처럼 다른 컴포넌트에 있어도 데이터를 공유할 수 있게 된다.
(query key 값으로 캐싱)
⇒ 클라이언트 서버 상태 동기화, 데이터 캐싱
TanStack Query 단점
TanStack Query를 모를 경우 러닝커브가 있고, 단순한 상태 관리에서는 과하게 느껴질 수 있다.
2. 옵티미스틱 업데이트 관점
비교하기 전에 옵티미스틱 업데이트에 대해 간단하게 설명을 하자면, 서버 응답을 기다리지 않고 사용자가 원하는 상태로 먼저 UI를 업데이트하여 사용자에게 빠르고 즉각적인 피드백을 주는 방식이다.
2-1. useState의 옵티미스틱 업데이트 관점
useState 장점
옵티미스틱 업데이트를 위해서 useState로 단순히 상태를 변경하는 것은 매우 쉽고 간단하다.
useState 단점
서버와 통신 후 결과에 따라 상태를 다시 조정해야 하고, 에러 발생 시 수동으로 상태를 롤백해야 한다.
그리고 사용자가 빠르게 여러 액션을 취할 경우, 서버 상태 불일치가 발생할 수 있다.
⇒ 서버 동기화 문제, 동시성 문제
2-2. TanStack Query의 옵티미스틱 업데이트 관점
TanStack Query 장점
서버 요청이 실패했을 때, onError 핸들러가 자동으로 롤백하여 UI와 서버 상태 간의 불일치를 해결해 준다.
onError: (err, _, context) => {
queryClient.setQueryData(["board", boardId], context?.prevData);
},
동시에 요청이 발생할 경우, 기존 쿼리를 일시 중단해서 동시성을 제어한다.
await queryClient.cancelQueries({ queryKey: ["board", boardId] });
또한 서버 응답이 성공하거나 실패하면, 데이터를 가져와 UI를 자동으로 최신 상태로 동기화해 준다.
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ["board", boardId] });
},
⇒ 자동 롤백, 동시성 제어, 데이터 동기화
TanStack Query 단점
기능을 구현하기 위해 여러 설정들이 필요하다. (onMutate, onError, onSettled)
3. 결론
useState는 단순한 로컬 상태 관리에 적합하지만, 서버와 상호작용하면서 복잡한 상태를 관리하기엔 적합하지 않다.
반면 복잡한 상태를 관리하거나 캐싱, 옵티미스틱 업데이트, 에러 핸들링 등 효율적으로 처리하기 위해서는 TanStack Query가 적합하다.
마치며...
지금까지 구현한 기능을 그저 "저 이런이런 기능 구현했어요!!" 라는 느낌으로 정리했던 것 같았다.
하지만 기능을 구현할 때 단순히 구현 방식과 결과만 나열하는 것에 그치기보다는 왜 이러한 방식을 택했고, 다른 방법과 비교했을 때 어떤 이점이 있었는지에 대한 고민과 근거가 뒷받침되어야 한다는 점을 깨달았다.
그래서 앞으로 선택을 할 때 논리적인 근거와 이유를 함께 정리하는 습관을 가져야겠다는 다짐을 하게 되었다....
기능 구현도 중요하지만, 그 구현을 뒷받침하는 이해와 고민이 개발자로서의 역량을 더 강화시킬 수 있다는 것을 요즘 크게 느끼고 있다.
천천히 정리하면서 생각 정리를 해봐야겠다!
'💜 리액트 > 라이브러리' 카테고리의 다른 글
[상태 관리 라이브러리] 내가 직접 사용해 본 Recoil, Zustand, Jotai (8) | 2024.11.05 |
---|---|
[Next.js] firebase 게시물 조회수 기능 구현 (생성, 조회, 갱신) (0) | 2024.08.29 |
[Tailwind] px 작성, 자동 rem 변환 (feat. pxr 단위) (0) | 2024.08.01 |
[Storybook] Next.js + Tailwind CSS + TypeScript 스토리북 적용하기 (0) | 2024.07.28 |
[에디터] React Quill 이미지 사이즈 조절 (quill-image-actions) (0) | 2024.07.02 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!