Framework
Version

Updates durch Mutationsantworten

Wenn Sie Mutationen behandeln, die Objekte auf dem Server **aktualisieren**, ist es üblich, dass das neue Objekt automatisch in der Antwort der Mutation zurückgegeben wird. Anstatt jede Abfrage für dieses Element erneut abzurufen und einen Netzwerkaufruf für Daten zu verschwenden, die wir bereits haben, können wir das von der Mutationsfunktion zurückgegebene Objekt nutzen und die vorhandene Abfrage sofort mit den neuen Daten aktualisieren, indem wir die Methode setQueryData des Query Clients verwenden.

tsx
const queryClient = useQueryClient()

const mutation = useMutation({
  mutationFn: editTodo,
  onSuccess: (data) => {
    queryClient.setQueryData(['todo', { id: 5 }], data)
  },
})

mutation.mutate({
  id: 5,
  name: 'Do the laundry',
})

// The query below will be updated with the response from the
// successful mutation
const { status, data, error } = useQuery({
  queryKey: ['todo', { id: 5 }],
  queryFn: fetchTodoById,
})
const queryClient = useQueryClient()

const mutation = useMutation({
  mutationFn: editTodo,
  onSuccess: (data) => {
    queryClient.setQueryData(['todo', { id: 5 }], data)
  },
})

mutation.mutate({
  id: 5,
  name: 'Do the laundry',
})

// The query below will be updated with the response from the
// successful mutation
const { status, data, error } = useQuery({
  queryKey: ['todo', { id: 5 }],
  queryFn: fetchTodoById,
})

Möglicherweise möchten Sie die onSuccess Logik mit einer wiederverwendbaren Mutation verknüpfen. Dafür können Sie einen benutzerdefinierten Hook wie diesen erstellen.

tsx
const useMutateTodo = () => {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: editTodo,
    // Notice the second argument is the variables object that the `mutate` function receives
    onSuccess: (data, variables) => {
      queryClient.setQueryData(['todo', { id: variables.id }], data)
    },
  })
}
const useMutateTodo = () => {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: editTodo,
    // Notice the second argument is the variables object that the `mutate` function receives
    onSuccess: (data, variables) => {
      queryClient.setQueryData(['todo', { id: variables.id }], data)
    },
  })
}

Unveränderlichkeit

Updates über setQueryData müssen auf eine unveränderliche Weise durchgeführt werden. Versuchen Sie **NICHT**, direkt in den Cache zu schreiben, indem Sie Daten (die Sie aus dem Cache abgerufen haben) an Ort und Stelle verändern. Es mag zunächst funktionieren, kann aber im Laufe der Zeit zu subtilen Fehlern führen.

tsx
queryClient.setQueryData(['posts', { id }], (oldData) => {
  if (oldData) {
    // ❌ do not try this
    oldData.title = 'my new post title'
  }
  return oldData
})

queryClient.setQueryData(
  ['posts', { id }],
  // ✅ this is the way
  (oldData) =>
    oldData
      ? {
          ...oldData,
          title: 'my new post title',
        }
      : oldData,
)
queryClient.setQueryData(['posts', { id }], (oldData) => {
  if (oldData) {
    // ❌ do not try this
    oldData.title = 'my new post title'
  }
  return oldData
})

queryClient.setQueryData(
  ['posts', { id }],
  // ✅ this is the way
  (oldData) =>
    oldData
      ? {
          ...oldData,
          title: 'my new post title',
        }
      : oldData,
)