React, Graphql - использовать мутацию для удаления из БД - PullRequest
0 голосов
/ 13 января 2020

Я пытаюсь создать простое демонстрационное CRUD-приложение с использованием React и Graphql

У меня есть готовый и работающий бэкэнд.

На внешнем интерфейсе я использую React с useQuery и useMutation.

У меня есть create, работающий с useMutation для создания данных, и чтение с useQuery для отображения данных.

Теперь я застрял с удалением. У меня есть кнопка сообщения, и я могу получить идентификатор сообщения для передачи функции useMutation для удаления сообщения.

Я просто застрял, заставляя его работать, если кто-нибудь может помочь.

App.tsx

import React, { useState } from 'react';
import './App.css';

import { RecipeData } from '../generated/RecipeData';
import { GET_ALL_RECIPES, ADD_RECIPE, DELETE_RECIPE } from '../queries';
import { useQuery, useMutation } from 'react-apollo-hooks';


const App: React.FC = () => {

  const [name, setName] = useState<string>('')
  const [description, setDes] = useState<string>('')
  const [id, setId] = useState<string>('')

  const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setName(e.target.value)
  }

  const handleDesChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setDes(e.target.value)
  }

  const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()
    createRecipe()
  };

  const handelDelete = (e: React.MouseEvent<HTMLButtonElement>) => {
    setId(e.target.parentElement.getAttribute("data-id"))
    deleteRecipe()
  }

  const [deleteRecipe] = useMutation(DELETE_RECIPE, {
    variables: { id }, refetchQueries: ['RecipeData']
  })

  const [createRecipe, { error }] = useMutation(ADD_RECIPE, {
    variables: { name, description }, refetchQueries: ['RecipeData']
  })
  if (error) {
    console.error('erroring : ', error)
  }

  const { data, loading } = useQuery<RecipeData | null>(GET_ALL_RECIPES, {
    suspend: false
  })

  if (loading || !data) return <div>Loading</div>

  return (
    <div className="App">
      <h1>Graphql</h1>
      <ul>
        {
          data.recipe !== null && data.recipe.map((recipe, i) => (
            <li key={recipe._id} data-id={recipe._id}>
              {recipe.name}
              <button onClick={handelDelete}>X</button>
            </li>
          ))
        }
      </ul>

      <form>
        <div>
          <label>Name</label>
          <input
            type="text"
            value={name}
            onChange={handleNameChange}
          />
        </div>
        <div>
          <label>Description</label>
          <input
            type="text"
            value={description}
            onChange={handleDesChange}
          />
        </div>
        <button onClick={handleClick}>Add Recipe</button>
      </form>
    </div>
  );
}

export default App;

query / index.tsx

import { gql } from 'apollo-boost';

export const GET_ALL_RECIPES = gql`
  query RecipeData{
    recipe{
      _id
      name
      description
    }
  }
`
export const ADD_RECIPE = gql`
  mutation addRecipe($name: String!, $description:String){
    addRecipe(name: $name, description: $description){
      _id
      name
      description
    }
  }
`

export const DELETE_RECIPE = gql`
  mutation deleteRecipe($id: Int!){
    deleteRecipe(_id: $id){
      _id
      name
      description
    }
  }
`   

Серверная

схема. js

exports.typeDefs = `

  type Recipe{
    _id: ID
    name: String
    description: String
  }

  type Query{
    recipe:[Recipe]
  }

  type Mutation{
    addRecipe(name: String!, description: String):Recipe
    deleteRecipe(_id: Int):Recipe
  }

`   

resolvers. js

exports.resolvers = {

  Query:{
    recipe: async(obj, args, {Recipe}, info) => {
      const allRecipes = await Recipe.find()
      return allRecipes
    }
  },
  Mutation:{
    addRecipe: async(obj, {name, description}, {Recipe}, info) => {
      const newRecipe = await new Recipe({
        name,
        description
      }).save()
      return newRecipe
    },
    deleteRecipe: async(obj, args, {Recipe}, info, {_id}) => {
      delete Recipe[_id];
    }
  }

}   

У меня нет демонстрационной версии извините, но выводится список с названием рецепта с полем ввода для добавления новых рецептов, эта часть работает.

У меня также есть кнопка удаления после каждого отображаемого рецепта. Я хотел нажать эту кнопку и удалить этот рецепт из списка.

В тот момент, когда я нажимаю эту кнопку удаления, я получаю следующее сообщение об ошибке на вкладке сети инструментов dev

message: "Variable "$id" got invalid value ""; Expected type Int. Int cannot represent non-integer value: """

1 Ответ

0 голосов
/ 13 января 2020
const handelDelete = (e: React.MouseEvent<HTMLButtonElement>) => {
  setId(e.target.parentElement.getAttribute("data-id"))
  deleteRecipe()
}

setID() нужно для чего-то (кроме передачи параметра)?

id не обновляется немедленно setID() (asyn c обновляется как setState - см. Документы) - значение не может использоваться в следующих deleteRecipe()

IMHO должно быть:

const handelDelete = (e: React.MouseEvent<HTMLButtonElement>) => {
  const delID = e.target.parentElement.getAttribute("data-id")
  deleteRecipe( delID )
}

и удаление с прямой передачей параметров:

const deleteRecipe = (id) =>  useMutation(DELETE_RECIPE, { 
  variables: { id }, refetchQueries: ['RecipeData']
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...