Ein Projekt bearbeiten
Ein Projekt bearbeiten
~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
GENAU dasselbe Muster wie useCreateProject (Kapitel 78), diesmal für PATCH – die REST-Semantik aus Kapitel 10 überträgt sich 1:1 auf die Hook-Struktur.
Den Update-Hook schreiben
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../api/client';
import type { Project } from '../types/project';
interface UpdateProjectInput {
id: number;
name?: string;
description?: string;
}
export function useUpdateProject() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ id, ...input }: UpdateProjectInput) => {
const response = await apiClient.patch<Project>(
`/projects/${id}`,
input,
{ headers: { 'Content-Type': 'application/merge-patch+json' } },
);
return response.data;
},
onSuccess: (updatedProject) => {
queryClient.invalidateQueries({ queryKey: ['projects'] });
queryClient.setQueryData(['project', updatedProject.id], updatedProject);
},
});
}Achtung: Content-Type: application/merge-patch+json MUSS EXPLIZIT gesetzt werden – der Standard-Header aus Kapitel 74 ist application/ld+json, was für PATCH NICHT die von Kapitel 10 erwartete Semantik ergibt.
setQueryData ZUSÄTZLICH zu invalidateQueries: DIESES aktualisiert den Cache SOFORT mit der Server-Antwort (KEIN zusätzlicher Request nötig, da die AKTUELLEN Daten BEREITS vorliegen), WÄHREND invalidateQueries die LISTE im Hintergrund neu lädt.
Ein editierbares Formular
import { useState, type FormEvent } from 'react';
import { useUpdateProject } from '../hooks/useUpdateProject';
import type { Project } from '../types/project';
function EditProjectForm({ project }: { project: Project }) {
const [name, setName] = useState(project.name);
const updateProject = useUpdateProject();
function handleSubmit(event: FormEvent) {
event.preventDefault();
updateProject.mutate({ id: project.id, name });
}
return (
<form onSubmit={handleSubmit}>
<input value={name} onChange={(e) => setName(e.target.value)} />
<button type="submit" disabled={updateProject.isPending}>
Speichern
</button>
{updateProject.isSuccess && <p>Gespeichert!</p>}
</form>
);
}
export default EditProjectForm;useState(project.name) initialisiert das Formular MIT den AKTUELLEN Werten – GENAU wie bei einem klassischen Symfony-FormType (createForm(ProjectType::class, $project)), nur auf React-Seite MANUELL nachgebildet.
Tipp: isSuccess ZUSÄTZLICH zu isPending/isError – TanStack Query MODELLIERT den GESAMTEN Lebenszyklus einer Mutation (idle → pending → success/error), NÜTZLICH für kurzzeitiges Feedback wie "Gespeichert!".