首页 > 解决方案 > React, Graphql - 如何使用 useMutation 钩子

问题描述

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

我设置了一个 mongoDB 和一个 useQury 挂钩,一切正常,我可以输出 useQuery 的返回。

我也在使用 apollo:generate 来生成类型

我遇到的问题是让 useMutation 起作用。

应用程序.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;

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

生成/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;
}

标签: reactjsgraphqlreact-hooks

解决方案


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

您当前的代码:

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

现在在函数外部提取useMutation钩子调用,并调用当您以正确方式单击时要调用的实际函数:handleClickcreateRecipe

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

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

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

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


推荐阅读