mingg IT

[React] React-Query 너무 편해서 눈물난다. 본문

FrontEnd

[React] React-Query 너무 편해서 눈물난다.

mingg123 2023. 2. 8. 17:22

우선 React-Query가 뭐냐 ? ChatGPT 에게 물어보자

 

React Query는 React 애플리케이션에서 비동기 데이터를 관리하고 업데이트하기 위한 라이브러리입니다. React 구성 요소에서 데이터를 쉽게 가져오고, 캐시하고, 업데이트할 수 있도록 설계되어 사용자에게 원활한 데이터 가져오기 경험을 제공합니다.

React Query의 주요 기능 중 일부는 다음과 같습니다.

  1. 데이터 캐싱: React Query는 가져온 데이터를 자동으로 캐싱하고 가능한 경우 재사용하여 네트워크 요청 수를 줄이고 애플리케이션 성능을 향상시킵니다.
  2. 백그라운드 새로 고침: React Query는 백그라운드에서 자동으로 데이터를 새로 고칠 수 있으므로 사용자가 페이지를 수동으로 새로 고칠 필요 없이 항상 최신 데이터를 볼 수 있습니다.
  3. 쿼리 관리: React Query는 필요에 따라 요청을 취소, 재시도 또는 중복 제거하는 기능을 포함하여 애플리케이션에서 여러 쿼리를 관리하는 편리한 방법을 제공합니다.
  4. 오류 및 로딩 상태: React Query는 로딩 및 오류 상태를 처리하기 위한 기본 제공 지원을 제공하므로 로딩 표시기와 오류 메시지를 사용자에게 쉽게 표시할 수 있습니다.
  5. Suspense 통합: React Query는 React Suspense API와 통합되어 구성 요소의 로드 상태를 쉽게 제어하고 전반적인 사용자 경험을 개선할 수 있습니다.

전반적으로 React Query를 사용하면 React 애플리케이션에서 비동기 데이터를 보다 쉽게 ​​관리하고 업데이트하여 사용자에게 보다 효율적이고 원활한 경험을 제공할 수 있습니다.

 
매우 깔끔하게 잘 설명해준다.

 

프론트엔드를 개발하다보면 POST나 UPDATE 이후, 갱신된 데이터를 다시 GET을 해와야 하는 상황을 종종 마주했을 것이다. 

또한, 해당 API 가 정상적으로 작동(200) 이라면 alert를 보여주거나, 특정 액션을 취해줘야하는 경우가 많다. 

 


우선 ReactQuery 를 사용하기 전에는 이런식으로 사용을 해주어야한다. 

const [children, setChildren] = useState([]);

 const data = await VaunceAppApis.postChildrenAsync(addressFormData);
 if (data) {
    console.log('success 자녀 등록 api', data);
	const getData = await VaunceAppApis.getChildrenAsync();
    setChildren(getData);
 }

이게 처음에 한 두 군데면 할만하겠지만.. 10개가 넘어가게되면 프론트엔드 개발자 입장에서 신경써줘야 할 부분들이 너무 많다. 

 

 

이런식으로 Query를 작성해준다. 

postChildrenAsync API가 성공하게되면,

onSuccess 함수안에서 invalidateQueries안에 있는 key 값(useGetChildrenKey)을 가진 useGetChildrenListQuery 함수를 호출하는 것이다. 

const useGetChildrenKey = ['app', 'children']
const useChildrenQuery = () => {
	const queryClient = QueryClient.useQueryClient();
	return QueryClient.useMutation(
		async (childrenForm: FormData) => {
			await VaunceAppApis.postChildrenAsync(childrenForm);
		},
		{
			onSuccess: () => {
				queryClient.invalidateQueries([...useGetChildrenKey]);
				alert('자녀 정보가 수정 되었습니다.');
			},
		}
	);
};

const useGetChildrenListQuery = () => {
	const result = useQuery({
		queryKey: [...useGetChildrenKey],
		queryFn: async () => {
			const res = await VaunceAppApis.getChildrenAsync();
			return res;
		},
		refetchOnWindowFocus: true,
	});
	if (result.isSuccess) {
		return result.data.vo || undefined;
	}
	throw Error;
};

useGetChildrenListQuery 해당함수에는 childrend을 GET 해오는 API 가 존재하기 때문에, POST가 성공하면 GET을 해오게 된다. 

 

그럼 이 만들어 놓은 함수를 어캐쓰냐?

let childrenFormData = new FormData();
childrenFormData.append(
    'childrenNameList',
    values.childList.map((child) => child.name).join(',')
);

const updateChildren = VaunceQueryState.useChildrenQuery();
updateChildren.mutate(childrenFormData);

이런식으로 mutate()함수를 이용해서 쓸 수 있다. 
저 두 줄만 사용해주면 주렁주렁 작성했던 코드를 작성하지 않아도 되고, 기본적으로 개발자가 신경쓸 부분이 훨 줄어든다.

 

// React-Query 사용 전 
 const data = await VaunceAppApis.postChildrenAsync(childrenFormData);
 if (data) {
 	console.log('success 자녀 등록 api', data);
 }

// React-Query 사용 후
updateChildren.mutate(childrenFormData);

이런식으로 쓸 수 있다.

 

이게 post 해오면 무조건 get 해와서 성능이나, 네트워크 이슈가 있을 수 있지않냐라고 처음에 생각했었는데.

post 해오고 무조건 get을 해오는게아니라, 갱신된 데이터를 봐야 하는 페이지에서 get을 해온다. 와우 굳. 

또한 해당 탭을 보고 있지 않으면,  그땐 get 해오지 않는 여러 옵션들이 있더라. 

500에러 났을경우에는 default로 3번 더 api를 호출해보는데 이것 또한 옵션으로 몇번 더 보낼지 설정할 수 있다. 

(react-query 붙이고나서 500에러가 3번난다고 당황하지 말길! )

 

공식문서에 매우 잘 나와있어서 심심할때마다 읽어보는 것도 괜찮을 듯 하다. 

 

Comments