- Published on
원하는 타이밍에 쿼리 요청을 트리깅하기
- Authors
- Name
- 윤영서
저희 회사에는 다음과 같이 구현되어야하는 페이지가 존재합니다.
한 페이지 내에 검색바와 글 목록이 같이 보여지고, 검색바에서 검색된 내용에 따라 글 목록이 변경되어야 합니다. 검색바로 검색할 수 있는 종류는 글 타입(셀렉트박스)
, 키워드(텍스트 인풋)
, 내가 쓴 글만 보기(체크박스)
로 총 세 종류입니다. 글 목록은 무한 스크롤로 구현되어야 했습니다.
무한 스크롤 되는 글 목록을 구현할때, 다음과 같이 tanstack-query
의 useInfiniteQuery
를 이용해 구현했습니다.
그런데 한가지 문제가 발생합니다. 검색바에서 검색어를 입력하고 submit 버튼
을 누를때만 쿼리를 요청해야 하는데, 이때 위에서 작성한 것처럼 파라미터에 글 타입(셀렉트박스)
, 키워드(텍스트 인풋)
, 내가 쓴 글만 보기(체크박스)
를 다 넣다보면 체크박스를 클릭할때마다, 셀렉트 박스를 클릭할 때마다 쿼리가 요청되어 버린다는 것이었습니다.
해결방법 1. 'enabled' 옵션을 이용해보자!
그래서 이 문제를 해결하기 위해 useInfiniteQuery
의 enabled
옵션을 이용해 쿼리 요청 타이밍 제어를 시도합니다. enabled
은 쿼리를 요청할지 말지를 결정하는 옵션으로, true
일때만 쿼리를 요청합니다. 그러나 이 옵션은 boolean
만 받을 수 있어서, submit 버튼
을 눌렀을때만 쿼리를 요청하려면 submit 버튼을 누른 상태
를 따로 관리해야 합니다.
그런데 생각해볼까요? submit 버튼을 누른 상태
를 어떻게 관리할 수 있을까요?
아래와 같은 상태가 있다고 해보겠습니다.
우리는 이 제출버튼이 눌렸고 응답이 왔는지-성공이니 실패니 하는 응답과 상관없이-를 제어할 수 있는 방법이 필요합니다. 당연하게도 검색바의 값이 submit
되는 시점에는 isSubmit이 true
로 변경되어야 할겁니다. 그런데 이 상태가 계속 유지되면 안되기 때문에, 쿼리가 요청되고 나서는 false
로 변경되어야 합니다.
다행히도 onSettled
콜백을 사용하면 이를 제어할 수 있을 것 같습니다!
그렇지만 이 방법을 사용하면 얼마 가지 않아 다시 머리가 아파질 것입니다.
onSettled
콜백은 deprecated 되었기 때문입니다. 이에 대한 디스커션을 확인할 수 있습니다.
그래서 이 콜백을 사용하지 않고 원하는 타이밍에 트리깅할 수 있는 다른 방법을 찾아내야했습니다.
해결방법 2. 'refetch'를 사용해보자!
tanstack-query의 공식문서를 뚫어져라 쳐다보고 있다가, refetch
를 사용하면 되지 않을까? 하는 생각이 들었습니다.
그러다가 제가 조언을 구하고 있던 지인분께서 이 방식이 공식문서에도 나와있다는 것을 알려주셨습니다.
쿼리를 자동으로 실행되지 않도록 설정하는 방법인데, enabled
를 false
로 설정하고, 쿼리 훅에서 반환한 refetch
를 사용해 쿼리를 요청하는 방식입니다. 그렇지만 이 방식에는 공식문서에도 나와있듯이, 바람직한 방법이 아닙니다. 공식문서에는 다음과 같이 나와있습니다.
Permanently disabling a query opts out of many great features that TanStack Query has to offer (like background refetches), and it's also not the idiomatic way. It takes you from the declarative approach (defining dependencies when your query should run) into an imperative mode (fetch whenever I click here). It is also not possible to pass parameters to refetch.
해석하면 이 방법은
- 백그라운드 리프레시와 같은 기능을 사용할 수 없습니다.
- 선언적이라기 보다는 명령적인 방식입니다.
refetch
에 매개변수를 전달할 수 없습니다.
위의 문제점들 중 첫번째와 두번째를 무시하더라도, 세번째 문제점은 원하던 방식을 구현할 수 없습니다. 검색된 값을 원하는 타이밍에 트리깅하기 위해서인데, 그러기 위해서는 매개변수를 받을 수 있어야 하기 때문입니다.
그렇기 때문에 또 다른 방법을 찾아야 합니다...
해결방법 3. 'fetchQuery'로 명시적으로 호출해보자!
위에서 언급한 제가 조언을 구하고 있던 지인분께서 fetchQuery
를 사용할 수도 있을 것 같다는 키워드를 주셨습니다.
✏️ 출처
https://tanstack.com/query/v4/docs/framework/react/guides/migrating-to-react-query-3#if-set-the-queryoptionsenabled-option-must-be-a-boolean-truefalse
https://github.com/TanStack/query/discussions/5279
https://tkdodo.eu/blog/breaking-react-querys-api-on-purpose
https://tanstack.com/query/v4/docs/framework/react/guides/disabling-queries
https://github.com/TanStack/query/discussions/957#discussioncomment-4247194
https://youngslog.medium.com/react-query%EC%9D%98-query-key-%EA%B5%AC%EC%A1%B0%ED%99%94%ED%95%98%EA%B8%B0-b8ddc6ec0f8e