지금 사용하는 모달중에 공유하는 모달을 제외하면 모두 api요청을 보내 데이터를 새로 받아야하는 경우이다.
모달 종류
- 폴더 추가, 폴더 삭제, 폴더 수정, 링크 추가, 링크 삭제
그래서 모든 곳에 쿼리를 적용해서 새로 데이터를 수정하는 과정을 거쳐야한다.
쿼리를 적용하기 전에 데이터를 새로 받아오기 위해서는 api를 통해 데이터를 받아오는 로직에 디펜던시 값을 주어서 디펜던시를 변경시키거나 라우터를 이용해 페이지 전체 reload, 페이지 이동으로 다시 요청을 보냈다.
const addFolder = async (data: FormValueTypes) => {
if (!data.folder) return;
const result = await postFolder(data.folder);
router.push(`/folder/${result[0].id}`);
};
하지만 이런 방식은 사용자가 계속 페이지 변경을 느껴야하기 때문에 불편하고 페이지를 새로 이동하면서 계속 서버에서 데이터를 새로 받아야하기 때문에 로딩구간이 많아진다. 그래서 우리는 리액트 쿼리의 refetch 기능을 활용해서 구현해보려고 한다.
refetch를 구현하기 전에 refetch되는 원리를 간단하게 알아보겠다. 지금 링크와 폴더 데이터를 각 쿼리키를 통해 저장하고 있다.

그래서 해당 쿼리키에 저장된 값을 사용해 데이터를 가져와 사용하는 것이다. 그리고 추가적으로 refetch하는 과정에서도 쿼리키를 사용하게 된다. 새로 받아야할 쿼리키를 지정하면 해당 쿼리키에 해당하는 데이터를 새로 받아오게 된다.
이제 직접 적용시켜보자.
우선 refetch되는 타이밍은 모달에서 api요청을 보내게되고 요청이 완료되면 해당 쿼리키의 데이터를 다시 받아오는 것이다.
const queryClient = useQueryClient();
queryClient에서 지원하는 기능을 사용하기 위해 useQueryClient를 불러온다. 그리고 모달은 특정 시점에 동작하기 때문에 useMutation을 사용해서 쿼리 로직을 구현해준다.
const { mutate, isPending } = useMutation({
mutationFn: (data: { folderId: string; folderName: string }) =>
putFolder(data.folderId, data.folderName),
onSettled: () => {
closeModal('edit');
},
});
이렇게 구현된 모달 api요청 로직이다. 모달이 동작하면 mutationFn에 등록된 api요청이 가게 되고 마지막에는 모달을 닫는 로직을 추가해줬다.
이제 진짜 refetch를 추가해준다.
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['folder'] });
},
refetch 시점은 api요청에 성공했을때 하게 된다. 그래서 onSuccess에 해당 동작을 넣어뒀다. 그리고 위에서 불러온 queryClient의 invalidateQueries기능을 사용해준다. 단어에서 유추할수 있듯이 유효하지 않은 쿼리로 만들어 데이터를 다시 받아오도록 하는 것이다. 그래서 refetch할 쿼리키를 넣어주면 쿼리키에 해당하는 데이터를 다시 받아오게 된다.

이제 확인해보겠다! 지금 위에 적용된 모달은 폴더 이름 편집 모달이다. 그래서 폴더 이름이 바뀌면 폴더 리스트를 보여주는 api를 refetch해야한다.
지금 깃허브로 되어있는 폴더 이름을 변경해보겠다. 전에는 페이지를 reload해야 동작했지만

변경하자마자 데이터를 받아오는 것을 확인할 수 있다. 사용자는 페이지 전환도 없이 바로 변경사항이 적용되는 것으로 느낄수 있다.
이런 신기술이 있나 싶지만 약점하나가 있다. 아무래도 서버에 데이터를 요청하고 받아오는 시간이 있기 때문에 솔직하게 동작이 바로바로 연결되지는 않는다. 중간의 약간 딜레이가 생길수밖에 없다.
지금 우리가 구현한 변경기능은 바로 사용자가 상태를 확인하거나 변경이 자주 일어나는 데이터가 아니기 때문에 상관없다. 하지만 좋아요 기능이나 즐겨찾기 기능이라면 딜레이가 생기면 상당히 불편할 것이다. 그래서 이런 약점을 보완하기 위해 optimistic update를 적용시켜줘야한다.
그래서 다음 포스트에서는 변경사항이 바로 적용되는 기능을 즐겨찾기 기능에 추가해보겠다.
쿼리를 배우면서 참 편한것을 이제 썼을까 싶다. 하지만 청천벽력같은 소식은 nextjs에서는 리액트 쿼리를 사용할 필요가 없다는 것이다. nextjs자체에서 캐싱을 지원하기 때문에 캐싱의 이유만으로 리액트 쿼리는 메리트를 잃는다. 하지만 아직 서버 컴포넌트와 SSR기능을 온전히 이해하고 사용하지 못하기 때문에 당장은 쿼리를 사용하지 않을까 싶다.
추가적으로 지금 nextjs 튜토리얼을 따라하는 중이다. 왜냐하면 app router를 적용시켜보고 싶다. 지금 사용하는 것은 페이지 라우터이고 불편함이 전혀 없지만 튜토리얼이 앱라우터 방식을 알려주고 있다면 앞으로 더 자주 사용될 여지가 있지 않을까. 점점 배울게 많아지고 깊어지는 기분이다. 더 바쁘게 움직여 보자.