【发布时间】: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<string>('')最终以mutation deleteRecipe($id: Int!){...结束 -
说你被卡住了并不是特别有用。预期的行为是什么——你看到的是什么行为?发生意外行为时,控制台中是否有任何错误 - 如果有,它们是什么?如果您查看开发工具,您的请求是否真的被发送了 - 如果是,它是否会返回预期的响应?
-
抱歉,我现在更新了问题,提供更多信息