Aujourd'hui et aujourd'hui, les rails avant React + back ...
Donc, cette fois, dans le prolongement de je suis parfaitement conscient de la commodité du générateur de code graphql, les «mutations» telles que l'enregistrement et la suppression, etc. Je ferai la part de.
Tout d'abord, nous allons créer un mécanisme pour ajouter TODO.
Nous avons préparé un champ de texte supplémentaire. Entrez une valeur ici et entrez exécutera un traitement supplémentaire.
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 ? (
...
Nous avons créé un mécanisme qui vous permet de saisir des caractères et d'effectuer un traitement supplémentaire avec enter.
Si vous rechargez l'écran après avoir appuyé sur Entrée, vous pouvez voir que TODO a été ajouté.
Comme vous ne pouvez pas voir le mouvement sans recharger, en plus du traitement supplémentaire, effacez le champ de saisie et réacquérir les informations de la liste.
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 = "";
}
}}
Aucune erreur particulière liée au type ne s'est produite.
Exécutez le processus d'enregistrement sans rien entrer et mettez en place un mécanisme qui provoque une erreur.
Ajout d'un champ d'erreur de validation à Todo
pour inclure les valeurs suivantes dans la réponse:
"errors":[{"field":"name","error":"blank"}]
Nous avons également ajouté un champ result
(booléen) pour voir si le résultat du processus a réussi.
Si result
est vrai
, rechargez la liste, et si faux
, créez un mécanisme pour afficher les informations d'erreur avec ʻ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}`);
+ });
+ }
+ },
+ });
Une erreur s'est produite car le type d'erreurs n'a pas été déclaré.
Je vais déclarer le type.
type ValidationErrorType = {
field: string;
error: string;
};
-errors.forEach(({ field, error }) => {
+errors.forEach(({ field, error }: ValidationErrorType) => {
alert(`${field} ${error}`);
});
L'erreur a été résolue et les messages d'erreur de validation peuvent maintenant être vus avec ʻalert`.
Comme la dernière fois, j'utiliserai graphql-code-generator
pour le nettoyer.
D'abord à partir des paramètres
Créez un répertoire pour les «mutations» séparément des «requêtes» et stockez-y la requête créée cette fois.
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
}
}
Maintenant, lorsque vous exécutez yarn generate
, vous aurez ʻuseAddTodoMutation pour ajouter TODO à
src / types.d.ts`.
Réécrivons le processus supplémentaire en utilisant ʻuseAddTodoMutation`.
-import { useTodosQuery } from "./types.d";
+import { useTodosQuery, useAddTodoMutation } from "./types.d";
+const [addTodo] = useMutation(ADD_TODO, {
+const [addTodo] = useAddTodoMutation({
Hmm? Une erreur est survenue.
Apparemment, "data" peut être "nul" ou "non défini".
Dans cet esprit, je vais le réécrire un peu.
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}`);
});
}
},
});
Il fallait quelques ajustements, mais c'est rafraîchissant en termes de source car il ne nécessite plus de requêtes et de déclarations de type: thumbsup:
Bien que ce soit une idée approximative, un bouton de suppression est fourni à côté de chaque TODO afin que le processus de suppression puisse être exécuté.
graphql/mutations/del_todo.graphql
mutation delTodo($id: ID!) {
delTodo(input: { id: $id }) {
todo {
id
}
}
}
Vous devez obtenir un identifiant pour identifier le TODO à supprimer.
Dans graphql / queries / todos.graphql
, seul le nom
de TODO est acquis, donc modifiez-le pour qu'il prenne ʻid`.
graphql/queries/todos.graphql
query todos {
todos {
+ id
name
}
}
Lancer yarn generate
a créé la fonction ʻuseDelTodoMutation dans
src / types.d.ts`.
Utilisez cette ʻuseDelTodoMutation pour permettre l'exécution du processus de suppression lorsque le bouton
supprimer` est cliqué.
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 } })}>Supprimer</button></li>)}
J'ai pu facilement implémenter le processus de suppression: tada:
Puisque l'acquisition de liste, le traitement d'addition et le traitement de suppression sont implémentés sur un écran et un composant, il se peut que le fichier soit légèrement plus volumineux.
Il est peut-être possible de définir la définition de type et les informations de requête dans un autre fichier et d'utiliser ʻimport`, mais je pense que la gestion peut devenir plus compliquée s'il y a plusieurs personnes.
Je pensais que si cela était développé selon les règles de graphql-code-generator
dans un sens, ce problème serait résolu.
Cette fois, je l'ai implémenté comme un exemple assez petit, donc je n'ai ressenti aucun obstacle à l'introduction. Je pense que c'est un outil LGTM: thumbsup:
Recommended Posts