如何在 x 时间后重新渲染反应(突变阿波罗)

Posted

技术标签:

【中文标题】如何在 x 时间后重新渲染反应(突变阿波罗)【英文标题】:How to re-render in react after x-time (Mutation Apollo) 【发布时间】:2020-12-23 21:14:08 【问题描述】:

我正在向 Shopify graphql 发送批量数据请求以获取商店中的所有产品,这可能需要一段时间,具体取决于商店有多少产品,因此 Shopify 建议不要使用 useQuery,而是使用发送批量请求更多关于 here 的 useMutation ,无论如何这是我的代码。

const BULK_INIT_MUTATION = gql`
    mutation 
        bulkOperationRunQuery(
            query: """
            
              products 
                edges 
                  node 
                    id
                    images
                      edges
                        node
                          id
                          originalSrc
                          altText
                        
                      
                    
                  
                
              
            
            """
        ) 
            bulkOperation 
                id
                status
            
            userErrors 
                field
                message
            
        
    
`;


const Index = () => 
    const [createBulkRequest,  data ] = useMutation(BULK_INIT_MUTATION);
    createBulkRequest();

    return <Page>Hi Index</Page>;
;

上面应该发起一个批量请求到 shopify 并且根据 Shopify 文档,他们需要几秒钟到几分钟之间的任何时间来准备好数据,以便我使用 useQuery 获取以下查询

query 
  currentBulkOperation 
    id
    status
    errorCode
    createdAt
    completedAt
    objectCount
    fileSize
    url
    partialDataUrl
  

当一切都很好时,上面的查询将返回类似这样的内容


  "data": 
    "currentBulkOperation": 
      "id": "gid:\/\/shopify\/BulkOperation\/720918",
      "status": "COMPLETED",
      "errorCode": null,
      "createdAt": "2019-08-29T17:16:35Z",
      "completedAt": "2019-08-29T17:23:25Z",
      "objectCount": "57",
      "fileSize": "358",
      "url": "https:\/\/storage.googleapis.com\/shopify\/dyfkl3g72empyyoenvmtidlm9o4g?<params>",
      "partialDataUrl": null
    
  ,
  ...

现在我感兴趣的是url 值,它应该链接到我可以获取实际数据的地址。

现在的问题是,除非 Shopify 服务器有足够的时间来处理我的请求,否则它将始终返回未定义的 url 值,我需要的是一种可能不断x时间后请求数据,直到它最终返回url,因此操作状态已完成,然后重新渲染。

我不确定解决此问题的最佳方法是什么,我正在考虑类似 setInterval 的方法,但我真的不确定。所以任何建议都会很有帮助,因为我已经坚持了几天了?

我已经尝试过如下的useEffect

const Index = () => 
    const [response, setData] = useState();

    const [createBulkRequest,  data ] = useMutation(BULK_INIT_MUTATION);
    createBulkRequest();

    useEffect(() => 
        const timer = setInterval(() => 
            const  loading, error, data  = useQuery(BULK_STATUS_QUERY);
            console.log('returned data', data);
            setData(data);
        , 5000);
        // clearing interval
        return () => clearInterval(timer);
    );

    return <Page>Hi Index</Page>;
;

但是这样做会引发此错误。

未处理的运行时错误错误:无效的挂钩调用。钩子只能是 在函数组件的主体内部调用。这可能发生 出于以下原因之一:

    您的 React 和渲染器版本可能不匹配(例如 React DOM) 您可能违反了 Hooks 规则 您可能在同一个应用程序中拥有多个 React 副本 有关如何调试的提示,请参阅 https://reactjs.org/link/invalid-hook-call 并解决此问题。

【问题讨论】:

useQuery 可以有 intervalskip 值 - 使用它们... onCompleted 检查值并使用跳过阻止下一个间隔 你能用类似的示例代码示例写一个详细的响应吗,因为我不确定跳过值的含义以及如何利用 onCompleted 检查...等。 skip 阻止执行,onCompleted 获取数据,可用于通过更改 skip 选项中使用的变量来停止下一次执行 【参考方案1】:

如果您需要在x 一段时间后安排某些任务以检索数据并更新某些已定义的状态,那么您可以使用setInterval() 方法调用useEffect 挂钩中的函数(确保清除返回该 useEffect 的间隔)

【讨论】:

当我这样做时,我收到此错误未处理的运行时错误错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一: 1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM) 2. 你可能违反了 Hooks 规则 3. 你可能有多个 React 副本同一个应用程序 请参阅reactjs.org/link/invalid-hook-call 以获取有关如何调试和修复此问题的提示。 请查看我的更新代码,了解我是如何实现 useEffect 的。

以上是关于如何在 x 时间后重新渲染反应(突变阿波罗)的主要内容,如果未能解决你的问题,请参考以下文章

如何在突变后更新阿波罗缓存(使用过滤器查询)

反应阿波罗突变和乐观更新

表达 http:graphql 突变上的 500 错误以在反应中从阿波罗客户端创建用户

如何在阿波罗客户端中将突变链接在一起

如何重新渲染 React 组件?

如何在没有参数的情况下进行graphql突变? (Vue 阿波罗)