【问题标题】:React, Graphql - useMutation to delete from DBReact,Graphql - useMutation 从数据库中删除
【发布时间】:2020-04-29 16:07:53
【问题描述】:

我正在尝试使用 React 和 Graphql 创建一个简单的演示 CRUD 应用程序

我的后端已经全部设置好并且可以正常工作了。

在前端,我将 React 与 useQuery 和 useMutation 结合使用。

我使用 useMutation 创建数据并使用 useQuery 读取数据以显示数据。

我现在坚持删除。我有一个帖子按钮,我可以获取帖子的 id 以传递给 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;

查询/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
    }
  }
`   

服务器端

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: Int):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, args, {Recipe}, info, {_id}) => {
      delete Recipe[_id];
    }
  }

}   

抱歉,我没有现场演示,但这会输出带有输入字段的食谱名称列表以添加新食谱,这部分有效。

在显示每个食谱后,我还有一个删除按钮。我想单击此按钮并将该食谱从列表中删除。

当我单击此删除按钮时,我在开发工具的网络选项卡中收到以下错误消息

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

【问题讨论】:

  • 我能看到的第一件事是您的突变需要一个整数 (ID),但您正在向它传递一个字符串。 const [id, setId] = useState&lt;string&gt;('') 最终以mutation deleteRecipe($id: Int!){... 结束
  • 说你被卡住了并不是特别有用。预期的行为是什么——你看到的是什么行为?发生意外行为时,控制台中是否有任何错误 - 如果有,它们是什么?如果您查看开发工具,您的请求是否真的被发送了 - 如果是,它是否会返回预期的响应?
  • 抱歉,我现在更新了问题,提供更多信息

标签: reactjs graphql


【解决方案1】:
const handelDelete = (e: React.MouseEvent<HTMLButtonElement>) => {
  setId(e.target.parentElement.getAttribute("data-id"))
  deleteRecipe()
}

setID() 需要一些东西(除了传递参数)?

id 不会被 setID() 立即更新(异步更新,如 setState - 请参阅文档) - 值不能用于关注 deleteRecipe()

恕我直言,应该有:

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']
})

【讨论】:

    猜你喜欢
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多