(썸네일 이미지 출처 - giphy)
프론트 엔드 상태 관리 방법좀 알려주세요! 😥
최근 회사 플랫폼을 리팩토링(사실상 리뉴얼) 하며 redux
와 redux-saga
를 도입해 상태 관리를 진행하고 있다.
선정 이유로는 mobx
보다 typescript, 함수형 프로그래밍 을 잘 지원해주고, contextAPI
보다 리렌더링 이슈를 잘 해결해주며, 무엇보다 높은 사용량을 기반으로 하는 커뮤니티가 있었다.
처음에는 시간이 조금 걸렸으나, 익숙해 진 후 redux
와 redux-saga
를 이용해 상태를 다루는 것은 많이 어렵지 않았다.
하지만 한편으로 계속해서 드는 의문감이 있었다.
이게 맞나...? 이렇게 비슷한 코드가 반복되는 구조가 맞나...??? 😐
이렇게 생각한 이유로는, 하나의 상태를 추가하기 위해서 비슷하게 생긴 reducer
, action
, type
를 만들어야 했고, 비동기 데이터를 위해 saga
와 api
도 만들어야 했기 때문이다.
이는 익숙해져서 어렵지는 않았지만 개발자로서 올바르지 않은.. 뭔가 비 효율적인 구조를 사용하는 것 같아 찝찝함이 항상 남아 있었다.
그러던 중 개인 프로젝트를 진행하며 상태 관리에 대해서 좀 더 알아보다가 새로운 방법론을 발견했다.
react-query
나 swr
을 이용해 server state
와 client state
를 나누는 것이었다.
이 전까지는 그것들을 나눈다고는 생각하지 못했던 나로써는 정말 흥미가 가는 방법이었다.
그래서 이번에는 redux
와 redux-saga
를 사용하는 것이 아닌 react-query
를 이용해 상태관리 하는 것을 정리해보고자 한다.
상태관리를 어떻게 구현할지 알아보기 전에, 우선 상태의 종류를 짚고 넘어가보자.
상태의 종류는 데이터의 Ownership에 따라 Server State
와 Client State
로 나눌 수 있다.
Server State
는 프론트엔드에서 백엔드로 데이터를 요청해 받아온 db
값으로 프론트엔드에서는 조작할 수 없는 값이다.
예를 들면 게시글 리스트라던지, 어떤 게시글의 내용, 댓글 수, 좋아요 수 등등이 있다.
이 값들은 프론트엔드가 자체적으로 상태를 조작할 수 없으며 백엔드로 조작해달라는 요청을 보내야 한다. (데이터 Ownership이 백엔드에 존재)
반대로 Client State
는 프론트엔드에서 조작하고 변경할 수 있는 프론트엔드에만 존재하는 값이다.
예를 들자면 modal
이 open인지 close인지 여부나, accordion
형식의 View
가 open인지 close 인지 등의 상태다.
사진을 예로 들자면, 알림
, 구독
, 메일
, 카페
, 블로그
탭 중에 어떤 탭이 click
되어 있는지에 대한 상태가 Client State
라고 할 수 있다.
사실 Redux
는 잘 만들어진 상태 관리 라이브러리다.
다운로드 수만 봐도 Redux
는 가장 많은 다운로드 수를 보여준다.
이는 그만큼 큰 규모의 커뮤니티, 사용자, 관심을 의미한다.
근데 왜 지금 나는 말짱히 가장 많은 사람들이 쓰는 Redux
를 보고 문제있다고 하는걸까?
사실 여기서 문제가 된다는 것은 조건부가 붙는다.
Redux
를 이용해 비동기 처리를 하려고 할 때
그럼 보통 언제 Redux
로 비동기 처리를 할까?
그건 바로 백엔드로 값을 요청해서 받아와야 할 때.
즉,
Server State
를 변경하고자 할 때 이다.
Redux
라이브러리 만으로는 비동기 처리를 구현하기 매우 어렵다.
이 같은 이유로 사람들은 Redux
에서 비동기 처리를 하기 위해 Redux-thunk
나 Redux-Saga
와 같은 라이브러리를 사용한다.
하지만 이 라이브러리들은 초기 세팅 및 사용법이 어렵고, 단번에 이해되는 형태가 아니다.
Redux-saga
의 경우 상태 하나 추가하려면 만들어야 하는 파일만 4개정도 된다.
(그리고 개인적으로 동작 방식이 React
스럽지 못한 느낌이다....)
그리고 비동기 처리를 하게되면 어느 시점에 값이 바뀌는지 예측하기가 어렵고 로딩 상태 관리도 개발자마다 제각각이다.
// false, true 로 로딩상태 관리
interface state_1 {
data : string;
isLoading : boolean;
}
// WAIT, REQUEST, SUCCESS, ERROR로 로딩상태 관리
interface state_2 {
data : string;
isLoading : 'WAIT' | 'REQUEST' | 'SUCCESS' | 'ERROR'
}
// loading, end 로 로딩상태 관리
interface state_3 {
data : string;
isLoading : 'loading' | 'end'
}
이 같은 문제들로 Redux
에서 Server State
를 관리하는데 문제점들이 발생했고, 개발자들은 react-query
, swr
과 같은 data-fetching
라이브러리를 사용하게 되었다.
다음 게시물에서는 실제 코드로 어떻게 작성하는지 알아보려 한다.
Redux
는 굉장히 잘 만든 상태 관리 라이브러리지만, 비동기 처리를 하기에 적합하지 않다.
때문에 비동기 처리가 필요한 Server State
는 react-query
나 swr
등의 data-fetching
라이브러리로 진행하는 추세이다.
언제나 하나에 만족하지 않고 계속 발전해나가는 개발자들이 정말 대단하다.
Redux
는 비동기 처리에 부적합.react-query
, swr
등의 사용이 증가하고 있음.+ 읽어주셔서 감사합니다.
+ 오타, 내용 지적, 피드백을 환영합니다. 많이 해주실 수록 제 성장의 밑거름이 됩니다.
Reference
아이고~ 잘보고 갑니다아