useQuery
와 useInfiniteQuery
에는 동일한 키를 사용할 수 없습니다.useQuery(['todos'], fetchTodos)
// 🚨 this won't work
useInfiniteQuery(['todos'], fetchInfiniteTodos)
// ✅ choose something else instead
useInfiniteQuery(['infiniteTodos'], fetchInfiniteTodos)
쿼리는 선언형입니다.
function Component() {
const { data, refetch } = useQuery(['todos'], fetchTodos)
// ❓ how do I pass parameters to refetch ❓
return <Filters onApply={() => refetch(???)} />
}
쿼리, refetching
을 명령형으로 생각하지만, "클릭"하는 데도 시간이 걸릴 수 있습니다.
refetch
의 뜻은 동일한 매개 변수를 사용하여 refetching
을 하는 것입니다.
function Component() {
const [filters, setFilters] = React.useState()
const { data } = useQuery(['todos', filters], () => fetchTodos(filters))
// ✅ set local state and let it "drive" the query
return <Filters onApply={setFilters} />
}
정확한 키를 알면 하나의 특정 목록을 대상으로 지정할 수 있습니다.
필요한 경우 모든 목록을 대상으로 지정할 수 있으므로 Updates from Mutation Responses 는 훨씬 더 유연해집니다.
function useUpdateTitle() {
return useMutation(updateTitle, {
onSuccess: (newTodo) => {
// ✅ update the todo detail
queryClient.setQueryData(['todos', 'detail', newTodo.id], newTodo)
// ✅ update all the lists that contain this todo
queryClient.setQueriesData(['todos', 'list'], (previous) =>
previous.map((todo) => (todo.id === newTodo.id ? newtodo : todo))
)
},
})
}
만약 list와 detail 구조가 많이 다르다면 이 기능이 작동하지 않을 수 있기 때문에 모든 list를 무효화 할 수 있습니다.
function useUpdateTitle() {
return useMutation(updateTitle, {
onSuccess: (newTodo) => {
queryClient.setQueryData(['todos', 'detail', newTodo.id], newTodo)
// ✅ just invalidate all the lists
queryClient.invalidateQueries(['todos', 'list'])
},
})
}
URL에서 필터를 읽어 어떤 목록에 있는 데이터를 알고 있으므로 정확한 queryKey
를 구성할 수 있다면, 이 두가지 방법을 결합하여 list
에서 setQueryData
를 호출하고 다른 모든 것을 무효화 할 수 있습니다.
function useUpdateTitle() {
// imagine a custom hook that returns the current filters,
// stored in the url
const { filters } = useFilterParams()
return useMutation(updateTitle, {
onSuccess: (newTodo) => {
queryClient.setQueryData(['todos', 'detail', newTodo.id], newTodo)
// ✅ update the list we are currently on instantly
queryClient.setQueryData(['todos', 'list', { filters }], (previous) =>
previous.map((todo) => (todo.id === newTodo.id ? newtodo : todo))
)
// 🥳 invalidate all the lists, but don't refetch the active one
queryClient.invalidateQueries({
queryKey: ['todos', 'list'],
refetchActive: false,
})
},
})
}
참조링크