React Query 이펙티브 리액트 쿼리 키

이재철·2023년 3월 2일
0

react-query

목록 보기
8/12
post-thumbnail

Caching Data

query key 특징

  • 쿼리 키는 고유해야 합니다.
  • react query가 캐시에서 키에 대한 항목을 찾으면 사용합니다.
  • useQueryuseInfiniteQuery에는 동일한 키를 사용할 수 없습니다.
useQuery(['todos'], fetchTodos)

// 🚨 this won't work
useInfiniteQuery(['todos'], fetchInfiniteTodos)

// ✅ choose something else instead
useInfiniteQuery(['infiniteTodos'], fetchInfiniteTodos)

Automatic Refetching

쿼리는 선언형입니다.

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} />
}

Always use Array Keys

참고 : React Query queryKey 관리하기

정확한 키를 알면 하나의 특정 목록을 대상으로 지정할 수 있습니다.
필요한 경우 모든 목록을 대상으로 지정할 수 있으므로 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,
      })
    },
  })
}

참조링크

profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글