React-Query에서 Dependency를 활용한 데이터 재요청
react-query를 이용하면서 특정 데이터가 변경되었을 때 데이터를 다시 받아오는 방법을 기록하기 위해 이 글을 작성한다.
// Search.tsx
import { useLocation, useParams, useSearchParams } from "react-router-dom";
import styled from "styled-components";
import { useQuery } from "react-query";
import { getDataByKeyword } from "../functions/api";
const Container = styled.main``;
interface ISearch {
// 생략
}
interface IResult {
results: ISearch[];
total_results: number;
total_pages: number;
}
export default function Search() {
const { keyword } = useParams();
const { data, isLoading } = useQuery<IResult>("search", () =>
getDataByKeyword(keyword as string)
);
console.log(`keyword: ${keyword}`);
console.log(data);
return (
<Container>생략</Container>
);
}
이 파일은 특정 단어를 검색했을 때, 해당 검색어에 따른 데이터를 보여줄 부분에 대한 파일이다. getDataByKeyword는 themoviedb api를 이용하여 데이터를 받아오는 함수이다. 만약 hero라는 단어를 검색했다면 http://localhost:3000/hero로 이동하게 된다. 그리고 console.log의 결과는 다음과 같다.
이제 super를 검색해보자. keyword가 super로 바뀌었으니 data 역시 바뀌어야 할 것이다.
total_page와 total_results의 숫자가 같다. 정말 우연히 두 키워드에 따른 데이터의 숫자가 일치한 것일 수도 있다. 그래서 이를 확인하기 위해 두 데이터의 results의 첫 번째 데이터를 확인해보자.
두 데이터가 일치함을 알 수 있다. 다른 데이터들 역시 똑같다. 즉, keyword는 변했지만 데이터는 변하지 않았다. 이 현상은 react-query가 내부적으로 사용된 쿼리의 키를 기반으로 데이터를 캐싱하기 때문이다.
const { data, isLoading } = useQuery<IResult>("search", () =>
getDataByKeyword(keyword as string)
);
현재 쿼리의 키는 고정된 값인 "search"이다. 즉, keyword가 변하더라도 "search"라는 키 자체의 값은 변하지 않았기에 새로운 데이터 요청을 하지 않은 것이다.
이러한 현상을 해결하기 위해서는 쿼리의 키를 아래처럼 설정하면 된다.
const { data, isLoading } = useQuery<IResult>(["search", keyword], () =>
getDataByKeyword(keyword as string)
);
여기서의 쿼리의 키는 "search"와 keyword 두 가지 값을 가지는 배열이다. 그렇기에 keyword가 변하면 쿼리의 전체 키도 변하게 되고, react-query는 변경된 키에 대한 데이터가 캐시에 없다고 판단하여 새로운 데이터를 요청하게 된다.
실제로 keyword가 hero에서 super로 변할 때, 새로 데이터를 요청하는 것을 확인할 수 있다.
이것들을 요약하지면 react-query는 키의 변화를 감지하여 해당 키에 연결된 데이터가 캐시에 없을 경우, 쿼리를 다시 실행하게 된다. 이를 이용해 쿼리의 키에 변화하는 데이터를 적용하여 데이터의 변화에 따른 데이터 재요청이 가능해진 것이다.