Apollo 客户端:如何对自定义事件执行查询

Posted

技术标签:

【中文标题】Apollo 客户端:如何对自定义事件执行查询【英文标题】:Apollo client: how to execute a query on custom event 【发布时间】:2020-10-22 23:11:21 【问题描述】:

无效的钩子调用。 Hooks 只能在函数组件的主体内部调用。这可能是由于以下原因之一:

    您可能有不匹配的 React 版本和渲染器(例如 React DOM) 您可能违反了 Hooks 规则 您可能在同一个应用中拥有多个 React 副本

它在handleclick上渲染两次。

import React, 
  useMemo,
  useState,
  useReducer,
  useEffect,
  useCallback,
  Fragment,
 from 'react';

import getAllFaqs from './faqQuery.graphql';
import getFaqById from './getFaqById.graphql';

import FaqTabIndex from './faqTabIndex';
import FaqCategoryList from './faqCategoryList';

import  useFaq  from '../../peregrine/talons/Faq/useFaq';
import  useFaqById  from '../../peregrine/talons/Faq/useFaqById';

const Faq = (props) => 
  const [faq, setFaq] = useState([]);
  const [faqCategory, setFaqCategory] = useState([]);
  const talonProps = useFaq(
    query: getAllFaqs,
  );
  const  data, error, loading  = talonProps;

  useEffect(() => 
    const tempData =  ...data ;
    setFaq([...tempData.faq]);
    setFaqCategory([...tempData.faqCategoryList]);
  , []);

  const handleClick = (catId) => 
    const talonProps = useFaqById(
      query: getFaqById,
      id: catId,
    );
    const  data, error, loading  = talonProps;

    console.log('====great data', data);
    useEffect(() => 
      const tempData =  ...data ;
      setFaq([...tempData.faq]);
    , [data]);
  ;

  const faqList = faq.length ? (
    <FaqTabIndex items=faq />
  ) : null;
  const catalog = faqCategory ? (
    <FaqCategoryList
      items=faqCategory
      handleClick=handleClick
    />
  ) : (
    nul
  );

  console.log('Thank Faq', faq);
  console.log('Thank Category ', faqCategory);
  return (
    <Fragment>
      faqList
      catalog
    </Fragment>
  );
;

export default Faq;

【问题讨论】:

您似乎正在修改 useEffect 中的状态,而不是应该在事件处理程序中触发状态更新 看起来,useFaqById 是一个钩子,你在 handleClick 中使用它, useEffect 也不应该在 handleClick 里面,这可能是你得到错误的原因 为什么useEffecthandleClick里面,这可能是错误的原因。 是的 useFaqById 是一个钩子,使用钩子 useQuery 并返回一个承诺。我想通过 handleclick 更新我的状态。 不要在处理程序中初始化钩子。挂钩必须在任何条件之前初始化一次。 【参考方案1】:

似乎您需要在单击按钮时执行查询,而不是立即执行它。该行为可以通过使用lazy query 来实现。

试试这样的:

../../peregrine/talons/Faq/useFaqById.jsx


import  useLazyQuery  from '@apollo/react-hooks';
import getFaqById from 'path/to/getFaqById.graphql';
export const useFaqById = useLazyQuery(getFaqById);

Faq.jsx

const [fetchFaqById, faqLoading, faqData] = useFaqById;

const handleClick = (catId) => 
   fetchFaqById(
      variables: 
         id: catId
      
   );


useEffect(() => 
   if (faqData) 
      setFaq([...faqData.faq]);
   
, [faqData])

【讨论】:

【参考方案2】:

你不直接在handleClick函数中调用Query,你必须只在main函数中声明,之后你必须使用。

import  useLazyQuery  from '@apollo/react-hooks';
import getFaqById from 'path/to/getFaqById.graphql';
const [useFaqById,data] = useLazyQuery(getFaqById);

然后就可以在handleClick函数里面调用了

const handleClick = (catId) => 
   useFaqById(
      variables: 
         id: catId
      
   );

【讨论】:

以上是关于Apollo 客户端:如何对自定义事件执行查询的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Apollo 在后台执行查询?

对自定义属性执行客户端验证

如何对自定义 AJAX 事件进行单元测试

有啥方法或包我们可以在 django 中对自定义原始 sql 查询执行过滤器(搜索)?

如何使用 apollo 客户端库创建带有角度参数的 graphql 查询

React - Apollo 客户端,如何将查询结果添加到状态