首页 > 解决方案 > 如何在 x 时间后重新渲染反应(突变阿波罗)

问题描述

我正在向 Shopify graphql 发送批量数据请求以获取商店中的所有产品,这可能需要一段时间,具体取决于商店有多少产品,因此 Shopify 建议不要使用 useQuery,而是使用 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>;
};

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

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

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

标签: graphqlshopifyapollonext

解决方案


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


推荐阅读