React,Graphql-如何使用useMutation钩子

时间:2020-01-09 22:10:20

标签: reactjs graphql react-hooks

我正在尝试使用React,Graphql,Typescipt和useMutation挂钩创建一个简单的演示。

我设置了一个mongoDB和一个useQury钩子,它们都能正常工作,并且我可以输出useQuery的返回值。

我也在使用apollo:gernerate生成类型

我遇到的问题是使useMutation正常工作。

App.tsx

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

import { RecipeData } from '../generated/RecipeData';
import { GET_ALL_RECIPES, ADD_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 handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setName(e.target.value)
  }

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

  const handleClick = (e: React.ButtonHTMLAttributes<HTMLButtonElement>) => {
      const [createRecipe] = useMutation(
        ADD_RECIPE,{
          onCompleted(data) {
            confirm(data);
          }
        }
      );
  }


  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={i}>{recipe.name}</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;

queries / 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($type: String){
    addRecipe(type: $type){
      name
      description
    }
  }
`   

Generated / AddRecipe.ts

export interface AddRecipe_addRecipe {
  __typename: "Recipe";
  name: string | null;
  description: string | null;
}

export interface AddRecipe {
  addRecipe: AddRecipe_addRecipe | null;
}

export interface AddRecipeVariables {
  type?: string | null;
}

1 个答案:

答案 0 :(得分:1)

您使用useMutation钩子的方式错误。

您当前的代码:

const handleClick = (e: React.ButtonHTMLAttributes<HTMLButtonElement>) => {
  const [createRecipe] = useMutation(ADD_RECIPE, {
    onCompleted(data) {
      confirm(data);
    }
  });
};

现在,在useMutation函数外部提取handleClick钩子调用,并以正确的方式调用实际调用的函数createRecipe

const [createRecipe] = useMutation(ADD_RECIPE, {
  onCompleted(data) {
    confirm(data);
  }
});

const handleClick = (e: React.ButtonHTMLAttributes<HTMLButtonElement>) => {
  createRecipe({ variables: { name, description }})
};

您必须在组件的顶层使用react挂钩,不要将它们放在函数,循环或条件语句中:)

此处的文档:https://www.apollographql.com/docs/react/data/mutations/