RTQ를 사용해서 한번만 데이터 fetching하는 기능 만들기

김삿갓의싱잉랩·2023년 10월 4일
0

👻 문제 상황

데이터를 불러올 때 tanstack query를 커스텀 훅으로 만들어서 사용하려는데 home에서 fetching 해오는 여러개의 데이터가 각 상태가 변할때마다 컴포넌트를 렌더링하게 돼서, 조건에 따라 페이지를 열었을 때 한번만 가져오는 데이터와 여러번 가져와야 하는 데이터를 구분할 필요가 있다.

문제 상황

기존 코드

문제 찾기

내가 생각한 에러 발생 이유는 useQuery가 Hook이라서 그렇다고 생각한다. 상태가 변하면 react에서 re-rendering이 발생하기 때문이다. 여기서 queryFn이 비동기 함수이기 때문에 각각 fetching하는 속도가 다르다. 그렇기 때문에 발생하는 순서가 달라서 re-redering이 발생한다고 생각한다.

해결방안 첫번째 생각

const defaultQueryOptions = {
	staleTime: 1000,
	cacheTime: 1000 * 60 * 5,
};

const keepQueryOptions = {
	staleTime: 1000 * 60 * 5,
	cacheTime: 1000 * 60 * 10,
	refetchOnWindowFocus: false,
};

단순하게 queryOption을 다르게 넣어주었다.
staleTime이 길어지기 때문에 이것은 임시 방편인 방법이었다.

해결방안 두번째 생각

이번에는 tanstack query에서 queryOption을 다룰 수 있는 Lazy Queries라는 방법을 사용해보기로 했다.

const Home = () => {
	const [filter, setFilter] = useState(true);

	const actionQueryKey = 'action';
	const romanceQueryKey = 'romance';
	const comedyQueryKey = 'comedy';
	const queryKey = 'movieDetail';

	const { data: actionData } = useQueryHook(
		actionQueryKey,
		() => getGenreMovieData(requests.fetchActionMovies),
		{
			staleTime: 1000,
			cacheTime: 1000 * 60 * 5,
			enabled: filter,
		},
	);

	const { data: romanceData } = useQueryHook(
		romanceQueryKey,
		() => getGenreMovieData(requests.fetchRomanceMovies),
		{
			staleTime: 1000,
			cacheTime: 1000 * 60 * 5,
			enabled: filter,
		},
	);

	const { data: comedyData } = useQueryHook(
		comedyQueryKey,
		() => getGenreMovieData(requests.fetchComedyMovies),
		{
			staleTime: 1000,
			cacheTime: 1000 * 60 * 5,
			enabled: filter,
		},
	);

	useEffect(() => {
		setFilter(false);
	}, [actionData, romanceData, comedyData]);

	const { data, isLoading, error } = useQueryHook(
		queryKey,
		() => fetchData(requests.fetchNowPlaying),
		defaultQueryOptions,
	);

	if (isLoading) return <div>로딩중...</div>;
	if (error) return <div>에러가 발생했습니다.</div>;

	console.log('start');

	console.log('actionData', actionData);

useEffect로 해당 데이터들의 상태 변화를 감시했다.
모든 상태변경이 완료되면 state의 상태를 바꿔서 다시 랜더링 되지 않도록 했다.

만약에 렌더링이 필요하다면 state를 변경하면 된다.

결론

이로써 불필요한 렌더링을 줄였다.

페이지에서 한번만 불러와도 되는 데이터들을 관리해야할 때는 enabled option을 사용해서 불필요한 cachetime과 staletime 설정을 해주지 않아도 될 것 같다.

profile
시스템 개발에 시간을 아끼지 말자

0개의 댓글