Heute und heute, Front React + Back Rails ...
Diesmal also als Fortsetzung von Ich bin mir der Bequemlichkeit des Graphql-Code-Generators sehr bewusst, "Mutation" wie Registrierung und Löschung usw. Ich werde den Teil von tun.
Zunächst erstellen wir einen Mechanismus zum Hinzufügen von TODO.
Wir haben ein zusätzliches Textfeld vorbereitet. Geben Sie hier einen Wert ein und geben Sie ein, um die zusätzliche Verarbeitung auszuführen.
src/App.tsx
+import { gql, useMutation } from "@apollo/client";
...
+const ADD_TODO = gql`
+ mutation addTodo($name: String!) {
+ addTodo(input: { name: $name }) {
+ todo {
+ id
+ name
+ }
+ }
+ }
+`;
const App = () => {
const { loading, data } = useTodosQuery();
+ const [addTodo] = useMutation(ADD_TODO);
...
</p>
+ <input
+ type="text"
+ onKeyPress={(e) => {
+ if (e.key === "Enter") {
+ addTodo({ variables: { name: e.currentTarget.value } });
+ }
+ }}
+ />
{loading ? (
...
Jetzt können Sie Zeichen eingeben und mit enter zusätzliche Verarbeitung durchführen.
Wenn Sie den Bildschirm nach dem Drücken der Eingabetaste neu laden, können Sie sehen, dass TODO hinzugefügt wurde.
Da Sie die Bewegung nicht sehen können, ohne sie neu zu laden, löschen Sie zusätzlich zur zusätzlichen Verarbeitung das Eingabefeld und erfassen Sie die Listeninformationen erneut.
src/App.tsx
...
- const { loading, data } = useTodosQuery();
+ const { loading, data, refetch } = useTodosQuery();
- const [addTodo] = useMutation(ADD_TODO);
+ const [addTodo] = useMutation(ADD_TODO, {
+ update() {
+ refetch();
+ },
+ });
...
onKeyPress={(e) => {
if (e.key === "Enter") {
addTodo({ variables: { name: e.currentTarget.value } });
+ e.currentTarget.value = "";
}
}}
Es ist kein bestimmter typbezogener Fehler aufgetreten.
Führen Sie den Registrierungsprozess aus, ohne etwas einzugeben, und fügen Sie einen Mechanismus ein, der einen Fehler verursacht.
Es wurde ein Validierungsfehlerfeld zu "Todo" hinzugefügt, um die folgenden Werte in die Antwort aufzunehmen:
"errors":[{"field":"name","error":"blank"}]
Wir haben auch ein result
Feld (Boolean) hinzugefügt, um zu sehen, ob das Ergebnis des Prozesses erfolgreich war.
Wenn result`` true
ist, laden Sie die Liste neu, und wenn false
, erstellen Sie einen Mechanismus zum Anzeigen von Fehlerinformationen mit alert
.
src/App.tsx
const ADD_TODO = gql`
mutation addTodo($name: String!) {
addTodo(input: { name: $name }) {
todo {
id
name
+ errors {
+ field
+ error
+ }
}
+ result
}
}
`;
src/App.tsx
const [addTodo] = useMutation(ADD_TODO, {
- update() {
- refetch();
- },
- });
+ update(
+ _cache,
+ {
+ data: {
+ addTodo: {
+ todo: { errors },
+ result,
+ },
+ },
+ }
+ ) {
+ if (result) {
+ refetch();
+ } else {
+ errors.forEach(({ field, error }) => {
+ alert(`${field} ${error}`);
+ });
+ }
+ },
+ });
Ein Fehler ist aufgetreten, weil der Typ "Fehler" nicht deklariert wurde.
Ich werde den Typ deklarieren.
type ValidationErrorType = {
field: string;
error: string;
};
-errors.forEach(({ field, error }) => {
+errors.forEach(({ field, error }: ValidationErrorType) => {
alert(`${field} ${error}`);
});
Der Fehler wurde behoben und Validierungsfehlermeldungen können jetzt mit "alert" angezeigt werden.
Wie beim letzten Mal werde ich graphql-code-generator
verwenden, um es zu bereinigen.
Zuerst aus den Einstellungen
Erstellen Sie ein Verzeichnis für "Mutationen" getrennt von "Abfragen" und speichern Sie die diesmal erstellte Abfrage dort.
codegen.yml
-documents: ./graphql/queries/*.graphql
+documents:
+ - ./graphql/mutations/*.graphql
+ - ./graphql/queries/*.graphql
graphql/mutations/add_todo.graphql
mutation addTodo($name: String!) {
addTodo(input: { name: $name }) {
todo {
id
name
errors {
field
error
}
}
result
}
}
Wenn Sie nun "Garn generieren" ausführen, haben Sie eine "useAddTodoMutation", um das TODO zu "src / types.d.ts" hinzuzufügen.
Lassen Sie uns den zusätzlichen Prozess mit useAddTodoMutation
umschreiben.
-import { useTodosQuery } from "./types.d";
+import { useTodosQuery, useAddTodoMutation } from "./types.d";
+const [addTodo] = useMutation(ADD_TODO, {
+const [addTodo] = useAddTodoMutation({
Hmm? Ein Fehler ist aufgetreten.
Anscheinend können "Daten" "null" oder "undefiniert" sein.
In diesem Sinne werde ich es ein wenig umschreiben.
const [addTodo] = useAddTodoMutation({
update(_cache, { data }) {
const result = data?.addTodo?.result || false;
const errors = data?.addTodo?.todo.errors || [];
if (result) {
refetch();
} else {
errors.forEach((e) => {
if (e) alert(`${e.field} ${e.error}`);
});
}
},
});
Es musste ein wenig angepasst werden, aber es ist in Bezug auf die Quelle erfrischend, da keine Abfragen und Typdeklarationen mehr erforderlich sind: thumbsup:
Obwohl es sich um eine grobe Idee handelt, befindet sich neben jedem TODO eine Schaltfläche zum Löschen, damit der Löschvorgang ausgeführt werden kann.
graphql/mutations/del_todo.graphql
mutation delTodo($id: ID!) {
delTodo(input: { id: $id }) {
todo {
id
}
}
}
Sie benötigen eine ID, um das zu löschende TODO zu identifizieren.
In graphql / queries / todos.graphql
wird nur der Name
von TODO erfasst. Ändern Sie ihn daher so, dass er id
annimmt.
graphql/queries/todos.graphql
query todos {
todos {
+ id
name
}
}
Durch Ausführen von "Garn generieren" wurde die Funktion "useDelTodoMutation" in "src / types.d.ts" erstellt.
Verwenden Sie diese useDelTodoMutation
, um den Löschvorgang zu aktivieren, wenn Sie auf die Schaltfläche Löschen
klicken.
src/App.tsx
-import { useTodosQuery, useAddTodoMutation } from "./types.d";
+import { useTodosQuery, useAddTodoMutation, useDelTodoMutation } from "./types.d";
+const [delTodo] = useDelTodoMutation({
+ update() {
+ refetch();
+ }
+});
-{data && data.todos.map(({ name }, i) => <li key={i}>{name}</li>)}
+{data && data.todos.map(({ id, name }, i) => <li key={i}>{name}<button onClick={() => delTodo({ variables: { id } })}>Löschen</button></li>)}
Ich konnte den Löschvorgang problemlos implementieren: tada:
Da wir die Listenerfassung, Additionsverarbeitung und Löschverarbeitung auf einem Bildschirm und einer Komponente implementiert haben, ist die Datei möglicherweise etwas größer geworden.
Es ist möglicherweise möglich, die Typdefinition und die Abfrageinformationen in einer anderen Datei zu definieren und "import" zu verwenden, aber ich denke, dass die Verwaltung bei mehreren Personen komplizierter werden kann.
Ich dachte, wenn dies in gewissem Sinne nach den Regeln des "Graphql-Code-Generators" entwickelt würde, wäre dieses Problem gelöst.
Dieses Mal habe ich es als ziemlich kleines Beispiel implementiert, sodass ich keine Hindernisse für die Einführung gespürt habe. Ich denke, es ist ein LGTM-Tool: thumbsup:
Recommended Posts