문제상황
생성 API를 호출한 뒤 성공한 경우 invalidateQueries
를 통해 기존에 조회했던 쿼리를 무효화시키고 데이터를 새로 조회해오고자 했다.
React Query DevTools를 통해 쿼리 조회 결과를 살펴보면 다음과 같다.
- 맨 처음에
["PRODUCTS",false]
쿼리를 먼저 조회하였다.- 해당 컴포넌트가 unmount 되면서 해당 쿼리 결과는
inactive
상태가 되었다.
- 해당 컴포넌트가 unmount 되면서 해당 쿼리 결과는
- 이후
["PRODUCTS",true]
쿼리를 조회하여 현재fresh
상태의 쿼리 결과를 가지고 있다.
이후 Product
리스트에 새 상품을 추가하면서 해당 쿼리 결과를 업데이트 시킬 필요가 있었고, 아래 두 가지의 방법 중 후자의 방법으로 업데이트를 처리하고자 했다.
1️⃣ 낙관적 업데이트 처리
2️⃣ 쿼리를 무효화 시켜 다시 조회
따라서 다음과 같이 invalidateQueries
를 사용하였지만 결과는 아래와 같았다.
queryClient.invalidateQueries("PRODUCTS")
fresh
상태에 있었던 ["PRODUCTS",true]
쿼리는 Last Updated를 통해 변경이 성공적으로 이루어졌음을 확인할 수 있다.
"PRODUCTS"
를 쿼리 키를 가지고 있는 쿼리들을 무효화시켰기 때문에 ["PRODUCTS",false]
쿼리 또한 위와 같이 업데이트 되면서 Last Updated가 변경되었어야 했지만 아래 사진과 같이 변경이 이루어지지 않았다.
참고
공식문서를 살펴보면 invalidateQueries
의 쿼리 매칭은 다음과 같다.
쿼리 무효화의 범위가 쿼리 키 범위의 상위에서 하위로 전파된다고 생각하면 된다.
- 해당 쿼리 키로 시작하는 모든 쿼리 무효화
import { useQuery, useQueryClient } from '@tanstack/react-query'
const queryClient = useQueryClient()
// 'todos'로 시작하는 쿼리키를 가지고 있는 모든 쿼리 무효화
queryClient.invalidateQueries(\['todos'\])
// 따라서 아래의 쿼리들은 모두 무효화 된다
const todoListQuery = useQuery(\['todos'\], fetchTodoList)
const todoListQuery = useQuery(\['todos', { page: 1 }\], fetchTodoList)
- 구체적인 쿼리 키(
하위 키
)를 전달하여 특정 변수가 있는 쿼리만 무효화
// { type: 'done' } 과 같이 구체적인 쿼리키 전달
queryClient.invalidateQueries(['todos', { type: 'done' }])
// 해당 쿼리는 무효화 된다
const todoListQuery = useQuery(['todos', { type: 'done' }], fetchTodoList)
const todoListQuery = useQuery(['todos', { type: 'done' }, { page: 1 }], fetchTodoList)
// 해당 쿼리는 무효화 되지 않는다
const todoListQuery = useQuery(['todos'], fetchTodoList)
- 하위 키가 없는 쿼리만 무효화
// invalidateQueries 호출 시 두 번째 인자로 { exact: true } 전달
queryClient.invalidateQueries(['todos'], { exact: true })
// 해당 쿼리는 무효화 된다
const todoListQuery = useQuery(['todos'], fetchTodoList)
// ['todos'] 쿼리 키의 하위 키(['todos' { type: 'done' }])을 가지고 있으므로
// 해당 쿼리는 무효화 되지 않는다
const todoListQuery = useQuery(['todos', { type: 'done' }], fetchTodoList)
해결
Stack Overflow의 해당 답변을 참고하였다.
React Query를 설정할 때 기본 옵션으로 주어지는 refetch 옵션 중 refetchOnMount
를 false로 설정해두어서 발생한 일이었다.
React Query의 refetch 관련 기본 옵션
refetchOnMount
: 마운트됨refetchOnWindowFocus
: 창에 다시 초점 맞춤refetchOnReconnect
:네트워크 재연결
["PRODUCTS",false]
에 해당하는 쿼리는 해당 쿼리를 호출하는 컴포넌트가 unmount 되면서 inactive
상태였기 때문에 invalidateQueries
가 동작하지 않았다.
따라서 다음과 같이 { refetchInactive: true }
를 통해 해결하였다.
queryClient.invalidateQueries(QueryKeys.PRODUCT, { refetchInactive: true });
'정리용' 카테고리의 다른 글
useLayoutEffect (0) | 2022.09.22 |
---|---|
[React] 일정시간동안 이벤트 발생이 없으면 콜백 함수 실행 (0) | 2022.08.09 |
크롬에서 막혀있는 포트 (0) | 2022.07.01 |
Proxy 서버로 CORS 해결하기 (0) | 2022.06.24 |
Docker 명령어 정리 (0) | 2022.05.25 |