Tags auswählen: ein Multi-Select
Tags auswählen: ein Multi-Select
~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Tags (Kapitel 12) sind SCHREIBGESCHÜTZT über die API – das Frontend liest sie NUR, um sie in einem Auswahl-Element ANZUZEIGEN, GENAU wie in Kapitel 42 beschrieben.
Alle Tags laden
import { useQuery } from '@tanstack/react-query';
import { apiClient } from '../api/client';
interface Tag {
'@id': string;
id: number;
name: string;
}
interface TagCollection {
'hydra:member': Tag[];
}
export function useTags() {
return useQuery({
queryKey: ['tags'],
queryFn: async () => {
const response = await apiClient.get<TagCollection>('/tags');
return response.data['hydra:member'];
},
staleTime: Infinity,
});
}staleTime: Infinity statt der 30 Sekunden aus Kapitel 73 – Tags ändern sich (Kapitel 12: NUR per Fixtures/Admin) SO SELTEN, dass ein wiederholtes automatisches Neuladen VERSCHWENDET wäre.
Das Multi-Select-Element
function TagSelector({
selectedIris,
onChange,
}: {
selectedIris: string[];
onChange: (iris: string[]) => void;
}) {
const { data: tags, isPending } = useTags();
if (isPending) {
return null;
}
function toggle(iri: string) {
if (selectedIris.includes(iri)) {
onChange(selectedIris.filter((current) => current !== iri));
} else {
onChange([...selectedIris, iri]);
}
}
return (
<div>
{tags.map((tag) => (
<label key={tag.id}>
<input
type="checkbox"
checked={selectedIris.includes(tag['@id'])}
onChange={() => toggle(tag['@id'])}
/>
{tag.name}
</label>
))}
</div>
);
}selectedIris: string[] speichert die AUSGEWÄHLTEN Tags DIREKT als IRI-Array – GENAU das Format, das useCreateTask (Kapitel 87) ERWEITERT um ein tags-Feld DIREKT an die API senden könnte, OHNE weitere Umwandlung.
Achtung: TagSelector ist eine "controlled component" (der AUFRUFENDE Elternteil hält den State über selectedIris/onChange) – dieses Muster erlaubt es, DENSELBEN Selector SOWOHL im Create- ALS AUCH im Edit-Formular wiederzuverwenden, OHNE eigene interne State-Logik.
Integration in das Task-Formular
const [selectedTagIris, setSelectedTagIris] = useState<string[]>([]);
// im JSX:
<TagSelector selectedIris={selectedTagIris} onChange={setSelectedTagIris} />
// beim Absenden:
createTask.mutate({ title, projectId, tags: selectedTagIris });Tipp: EIN ECHTES Dropdown/Combobox (statt Checkboxen) wäre bei VIELEN Tags BENUTZERFREUNDLICHER – Bibliotheken wie react-select lösen DIESES Problem fertig, das GRUNDPRINZIP (IRI-Array als Zustand) bleibt UNABHÄNGIG von der gewählten UI-Bibliothek GLEICH.