首页 > 解决方案 > React,Graphql CRUD 应用程序 - 删除突变删除列表中的第一个

问题描述

我正在尝试使用 Graphql 在 React 中创建一个简单的 CRUD 演示。

我有后端工作,我有创建和阅读。

我正在输出一个食谱名称列表,并有一个要添加到列表中的输入字段。

列表中的每个配方都有一个删除按钮来删除该配方。

我有删除工作,但不是删除配方点击它总是删除列表中的第一个配方。

正确的 id 被传递给 delete Mutation 但网络选项卡显示列表中第一个配方的 id。

谁能看到我做错了什么。

服务器端

schema.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: ID):Recipe
  }

`

解析器.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, { id }, { Recipe }, info) => {
      const recipe = await Recipe.findOneAndRemove({ id })
      return recipe
    }
  }
}

客户

查询/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: ID!){
    deleteRecipe(_id: $id){
      _id
      name
      description
    }
  }
`

应用程序.tsx

import React, { useState, useEffect } 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 [recipeId, setRecipeId] = useState<string>('')

  useEffect(() => {
    deleteRecipe()
    console.log('recipeId = ', recipeId)
  }, [recipeId])

  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>) => {
    setRecipeId(e.target.parentElement.getAttribute("data-id"))
  }

  const [deleteRecipe] = useMutation(DELETE_RECIPE, {
    variables: { id: recipeId }, 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;

标签: reactjsgraphql

解决方案


推荐阅读