sns-project를 진행하던 중, 문제가 발생하였습니다.
메인페이지는 최신 게시물을 나열하는 무한스크롤 기능을 지원하고 있으며, 새로운 게시물은 모달을 통해 작성하는 형태입니다.
새로운 게시물을 작성하면 게시물 목록에 맨 처음에 업데이트 되길 원했습니다.
const queryClient = useQueryClient();
const { mutateAsync: createPostMutate } = useCreatePost({
onSuccess: () => {
queryClient.invalidateQueries(PostKey.getPostList());
unmount(POST_MODAL);
},
onError: error => alert({ message: getErrorMessage(error.code) })
});
첫번째로 시도한 방법은 invalidateQueries
를 사용해 리스트를 만료시켜 재호출 하는 방법을 사용했습니다.
이 방법도 정상적으로 작동하나 문제가 발생하였습니다.
메인페이지는 무한스크롤을 지원하기 때문에 만료시키면 첫페이지부터 다시 api를 호출하여 너무 많은 호출이 발생하게 됩니다.
만약 10페이지 까지 게시물을 로딩한 상태에서 invalidateQuries
를 실행시키면 다시 1페이지부터 10페이지까지 api
를 재호출하게 됩니다.
가장 간편한 방법이긴 하나, 위 상황에서 사용하기에는 맞지 않는 것 같습니다.
const queryClient = useQueryClient();
const { mutateAsync: createPostMutate } = useCreatePost({
onSuccess: post => {
queryClient.setQueryData<InfiniteData<PostClient[]>>(PostKey.getPostList(), data => {
const _pages = data?.pages ? [...data.pages] : [];
const pages = [
[{ ...post, comments: [], reactions: [], user: userData as Account }],
..._pages
];
const pageParams = data?.pageParams ?? [];
return { pages, pageParams };
});
unmount(POST_MODAL);
},
onError: error => alert({ message: getErrorMessage(error.code) })
});
setQueryData
는 캐시된 데이터를 즉시 업데이트하는데 사용할 수 있는 함수입니다. 자세한 내용은 링크를 통해 확인하실 수 있습니다.
이 함수를 사용해 pages
의 맨 앞에 새로운 게시물을 추가하고 바로 업데이트 해주었습니다.
이 방법을 사용하여 수동으로 업데이트 해주면, api의 호출을 유발하지 않고 추가가 가능합니다.
이 방법이 좋은가? 에 대한 답변은 잘 모르겠습니다. 게시물 삭제와 같은 기능의 경우, 많은 게시물을 순회하면서 해당하는 게시물을 찾아 제거해주는 과정이 필요한데, 게시물이 많으면 많을수록 순회하는 과정에서 많은 리소스가 발생할것 같습니다.
스크롤이 많이 진행되면 상단 게시물을 제거하면서 양방향 무한스크롤을 구현하던지 추후 대책을 마련해야 할 것 같습니다.