[RAILS] Ich bin mir der Bequemlichkeit des Graphql-Code-Generators Teil 2 sehr bewusst

Einführung

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.

Versuchen Sie es vorerst nach Apollos Formel

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.

スクリーンショット 2020-09-22 12.44.46.png

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.

スクリーンショット 2020-09-22 14.18.50.png

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.

Versuchen Sie es etwas bequemer zu machen

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.

スクリーンショット 2020-09-22 16.10.28.png

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.

スクリーンショット 2020-09-22 16.15.46.png

Wie beim letzten Mal werde ich graphql-code-generator verwenden, um es zu bereinigen.

Verwenden Sie den Graphql-Code-Generator

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.

スクリーンショット 2020-09-22 21.01.17.png

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:

Versuchen Sie, den Löschvorgang auf die gleiche Weise zu implementieren

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.

スクリーンショット 2020-09-27 23.50.47.png

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:

add-del.gif

Schließlich

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

Ich bin mir der Bequemlichkeit des Graphql-Code-Generators Teil 2 sehr bewusst
Ändern Sie nur einen Teil des Textes
Ich habe die Quelle von ArrayList gelesen, die ich gelesen habe
Ich habe die Quelle von Integer gelesen
Ich habe die Quelle von Long gelesen
Ich habe die Quelle von Short gelesen
Ich habe die Quelle von Byte gelesen
Ich habe die Quelle von String gelesen
Ich habe die interne Verarbeitung von Retrofit untersucht
[Tag: 5] Ich habe die Grundlagen von Java zusammengefasst
Ich habe den Teil von java.net.URL # getPath überprüft
Ich habe die Grundlagen der Zeicheneingabe verstanden
Bildregistrierung? Natürlich kann (kann) ich nicht ~ part2 ~
[Java] Der verwirrende Teil von String und StringBuilder
Ich habe die Eigenschaften von Java und .NET verglichen
Ich möchte den Inhalt der Absicht var_dump
Ich habe versucht, den Profiler von IntelliJ IDEA zu verwenden
Ich habe die Anzahl der Taxis mit Ruby überprüft
Probieren Sie Progate Free Edition [Java I]
Der Teil, dem ich in "Einführung in Ajax in Java-Webanwendungen" von NetBeans verfallen war