制作自定义反应钩子以执行查询和突变

Posted

技术标签:

【中文标题】制作自定义反应钩子以执行查询和突变【英文标题】:Making a custom react hook to perform queries and mutations 【发布时间】:2021-12-29 17:03:26 【问题描述】:

这就是我如何使用 ApolloClient 来执行我的 CRUD 操作,我如何使这个过程可重用?我有许多页面使用相同的逻辑,并且为每个页面编写这些函数非常耗时且相似。当我尝试在我的功能组件之外使用 useMutation 时出现错误,可能是我需要使用自定义钩子,我该如何实现它

import  useQuery, useMutation, useLazyQuery  from '@apollo/client'

获取查询

  const 
    data: dataQuery,
    loading: loadingQuery,
    error: errorQuery,
   = useQuery(SEARCH_ALL_ITEMS, 
    variables:  profileId ,
  )

添加突变

  const [addRow,  data: dataAdd, loading: loadingAdd, error: errorAdd ] = useMutation(
    CREATE_ITEMS,
    
      refetchQueries: [ query: SEARCH_ALL_ITEMS, variables:  profileId  ],
      onCompleted: () => 
        notification.success(
          message: 'Success',
          description: 'Information is added',
        )
      ,
    ,
  )



 useEffect(() => 
      if (loadingQuery || loadingAdd || loadingDelete || loadingUpdate || loadingLazyQuery) 
        setLoading(true)
       else 
        setLoading(false)
      ,[loadingQuery, loadingAdd, loadingDelete, loadingUpdate]

【问题讨论】:

【参考方案1】:

我会选择这样的东西

import  useQuery, useMutation, useLazyQuery  from '@apollo/client'

export const useQueryMutation = (query, variables: queryVariables, 
  mutations:  add, update, delete ) => 
  const 
    data: dataQuery,
    loading: loadingQuery,
    error: errorQuery,
   = useQuery(query, 
    variables: queryVariables,
  )

  const [addRow,  data: dataAdd, loading: loadingAdd, error: errorAdd ] = useMutation(
    add,
    
      variables: mutationVariables,
      refetchQueries: [ query, variables: queryVariables ],
      onCompleted: () => 
        notification.success(
          message: 'Success',
          description: 'Information is added',
        )
      ,
    ,
  );

  const [updateRow,  data: dataUpdate, loading: loadingUpdate, error: errorUpdate ] = useMutation(
    update,
    
      refetchQueries: [ query, variables: queryVariables ],
      onCompleted: () => 
        notification.success(
          message: 'Success',
          description: 'Information is updated ',
        )
      ,
    ,
  );

const [deleteRow,  data: dataDelete, loading: loadingDelete, error: errorDelete ] = useMutation(
    delete,
    
      refetchQueries: [ query, variables: queryVariables ],
      onCompleted: () => 
        notification.success(
          message: 'Success',
          description: 'Information is deleted ',
        )
      ,
    ,
  );

  return 
    query: 
      data: dataQuery,
      loading: loadingQuery,
      error: errorQuery
    ,
    mutation: 
      add: 
        mutate: addRow,
        data: dataAdd,
        loading: loadingAdd,
        error: errorAdd
      , 
      update: 
        mutate: updateRow,
        data: dataUpdate,
        loading: loadingUpdate,
        error: errorUpdate
      , 
      delete: 
        mutate: deleteRow,
        data: dataDelete,
        loading: loadingDelete,
        error: errorDelete
      , 
    ,
   loading: loadingQuery || loadingAdd || loadingDelete || loadingUpdate || loadingLazyQuery
  

并像使用它

const query: data, mutation: add, update, delete, loading = useQueryMutation(query: SEARCH_ALL_ITEMS, variables:  profileId ,  mutation:add: CREATE_ITEMS, update: UPDATE_ITEMS, delete: DELETE_ITEMS );

【讨论】:

谢谢,这似乎可以工作。你能解释一下这里发生了什么吗? useQueryMutation 只是一个简单的 .js 文件? 我的意思是,我还有其他用于更新和删除的突变,我将如何仅使用所需的查询,例如,仅添加或仅更新。 示例:``` const query: data, mutation: mutate = useQueryMutation(query: GET_ALL_CATS, mutation: REMOVE_CAT); ``` 是的,它们是从钩子返回的。你可以像const mutation: mutate: addRow = useQueryMutation(...)const mutation: mutate: updateRow = useQueryMutation(...)const mutation: mutate: deleteRow = useQueryMutation(...)一样访问它们,然后在<Button onClick=(() => deleteRow(variables: id: 1)>click</Button>中访问它们 哦,我现在可能明白你的问题了......让我更新我的答案【参考方案2】:

一个可靠的选择是用于 apollo 的 GraphQL 代码生成器: https://www.graphql-code-generator.com/docs/plugins/typescript-react-apollo

这个插件可以让你在你的仓库中创建一个新文件,例如:searchAllItems.graphql

并将graphql查询/突变粘贴在其中(gql``模板函数中的内容。

当你运行生成器时,它会为你创建钩子。

如果您的查询名为“query SearchAllItems ... ”

那么您将已经为您设置了一个名为“useSearchAllItemsQuery”的钩子。

【讨论】:

以上是关于制作自定义反应钩子以执行查询和突变的主要内容,如果未能解决你的问题,请参考以下文章

如何模拟反应自定义钩子返回值?

在自定义反应钩子中使用 axios

在反应本机应用程序中使用 AWS Amplify 在 GraphQL 突变中出错

反应:带有自定义钩子的滑块无法正常工作

如何使用自定义钩子访问织物对象以将背景图像添加到画布?

使用钩子从反应中调用 GraphQL 突变的正确方法