우리가 전역 상태관리를 뒤엎은 이유📌

리덕스는 상태 관리 라이브러리이다.
컴포넌트의 상태 관리 로직들을 따로 분리시켜 효율적으로 관리하며
전역 상태 역시 함께 관리하는 라이브러리이다.

우리는 프로젝트 초기 유용한 Hook들과 거대한 상태를 보다 손쉽게 다룰 수 있다는 점에서
리덕스를 가져와 사용했다.

문제 발생😡

프로젝트를 진행한지 4주 정도가 지났을 때
우리의 store는 굉장히 비대해져있었다.

전역 상태를 가져와 사용하기위해 쓴다기보단
호출한 API에서 가져온 데이터를 조작하고 관리하기 위해 쓴다는 느낌이 더 강했으며 단일 컴포넌트 역시 전역 상태 사용을 줄이고 api로 상태를 요청 후 사용하였다.

그러다보니 어느새 store는 전체적으로 전역상태 관리보단
api 통신의 중앙화를 위한 느낌이 더 많이 나게 되었고

우리는 store를 비동기 통신의 중앙화 시스템이 아닌
완벽한 전역 상태 관리를 위해 다른 해결책을 생각해냈다.

React Query 도입🔥

React Query는 *Server State를 관리하는 라이브러리이다.

여기서 *Server State란

  • 원격에 위치한 공간에 저장되며 Client가 소유하거나 제어하지 않는다
  • 데이터를 가져오고 업데이트하기 위해선 비동기 API가 필요하다
  • 다른 사람과 함께 사용하며, 내가 모르는 사이에 업데이트될 수 있다
  • Client에서 사용하는 데이터가 “유효 기간이 지난(out of date)” 상태가 될 가능성을 가진다.

우리는 전역상태와 단일 컴포넌트에서의 비동기 통신을 완전히 분리하기위해
React Query 라이브러리를 사용하여 이 Server State를 잘 굴려보기로 하였다.

React Query 사용✅

React Query는 정말 매력적인 라이브러리다.

우린 React Query가 제공하는 다양한 기능 중 두 가지의 강력한 기능에 매력을 느꼈는데

  1. 데이터를 불러오거나 Create, Update, Delete 요청을 할 때 isLoading, isSuccess와 같은 데이터 fetching에 대한 여러 가지 config
  2. 받아온 Query들이 들고 있는 Unique Key를 통해 특정 query를 queryClient의 invalidateQueries 메소드를 활용하여 할 수 있는 강제 Refresh 기능
const { isLoading, error, data, isFetching } = useQuery("repoData", () =>
    fetch(
      "https://api.github.com/repos/tannerlinsley/react-query"
    ).then((res) => res.json())
  );

  if (isLoading) return "Loading...";

  if (error) return "An error has occurred: " + error.message;
  1. 우린 받아오는 data 외에 loading이나 error등 다양한 Flag들을 보다 편리하게 활용할 수 있었다.
	const { mutate: deleteClass } = useMutation(
		(classid: string) => api.deleteClass(classid),
		{
			onSuccess: () => {
				console.log('1');
				dispatch(closeModal());
				queryClient.invalidateQueries('teachCard');
				navigate('/');
			},
		}
	);
  1. Create, Update, Delete와 같이 Mutation 요청 시 서버에 값이 변하므로
    QueryClient에서 제공하는 invalidateQueries 메서드를 통해 해당 Key를 들고 있는 Query를 refetch가 발생하게 하여 전역 상태와 같은 효과로 Refresh 하였다.

결론🎭

개별 Component는 살짝 커진듯한 느낌을 주었지만 순수하게 Client 상태만을 관리하는데 Store를 사용할 수 있어 Store의 코드과 굉장히 단순해졌다는 점

좋은 웹페이지 즐겨찾기