Apollo 加载在道具更改时总是错误的

Posted

技术标签:

【中文标题】Apollo 加载在道具更改时总是错误的【英文标题】:Apollo loading is always false on props change 【发布时间】:2020-04-20 09:21:22 【问题描述】:

我是阿波罗的新手。我面临的问题是在初始(挂载/渲染)网络调用时进行,而在道具更改时却没有。

以下是我的应用程序的简化结构。

<Component (has filters in state)>
  <QueryComponent filters = ...filters (passed to query)>

    <Table onChange/>

  </QueryComponent>
<Component/>
QueryComponent Code

export const QueryComponent = ( callback, filter ) => 

  // Data transformation from filter to vars(expected by Query)

  return (
    <Query
      handleLoading
      query=query
      returnPartialData
      variables=vars
      fetchPolicy="network-only"
      callback=callback
      getData=function
      entityType="xx"
    />
  );
;

Query returns ApolloQuery

<ApolloQuery
    returnPartialData=returnPartialData
    partialRefetch=partialRefetch
    ...rest
  >
    
      (
        data,
        loading,
      ) => 
        if (loading) 
          return handleLoading
            ? (
              <Loading />
            )
            : callback(
              loading,
            );
        

        const queryData = data && getData(data);
        const hasValidData = !!queryData && !!Object
          .values(queryData)
          .filter((val) => !!val)
          .length;

        if (!hasValidData) 
          return passThruMissingData
            ? callback(
              loading,
              ...queryData,
            )
            : (
              <EntityNotFound
                type=entityType
              />
            );
        

        let strippedData =  ...queryData ;
        const isValueAnArray = Object.values(strippedData)[0] instanceof Array;

        if (isValueAnArray) 
          strippedData = transform(
            strippedData,
            (result, value, key) => 
              value.forEach(deepStripInvalid);

              // eslint-disable-next-line no-param-reassign
              result[key] = value;
            ,
          );
         else 
          deepStripInvalid(strippedData);
        

        return callback(
          ...strippedData,
        );
      
    
  </ApolloQuery>

并且QueryComponent 有一个包装器,它具有Query as ApolloQuery 形式react-apollo 并且当正在加载 为真时返回加载器。

&lt;Table/&gt; 组件中,我有一个处理程序来更新组件中的过滤器,这些过滤器向下流入&lt;QueryComponent /&gt;

在初始渲染时,过滤器被向下传递,我可以看到网络调用已经进行,加载状态一秒钟为真,然后变为假。当我与表交互时,调用 onChange 更新过滤器并将它们传递给 Query,但加载状态返回 false 并且没有网络调用。

我也尝试设置fetchPolicy="network-only"fetchPolicy="no-cache",但仍然没有网络调用。

注意:目前后端没有数据,所以初始查询返回一个空数组。

我期望的行为:当过滤器被改变时,查询被再次调用并且应该有一个网络调用。

注意2:如果我强制卸载并重新安装&lt;QueryComponent&gt;,则会发出网络请求,但我更愿意使用 Apollo 的加载状态来处理。

react-apollo:“版本”:“2.5.8”

阿波罗:“版本”:“2.21.0”

已编辑以包含更多详细信息。

【问题讨论】:

介意分享QueryComponent 代码吗?似乎它可能只在 componentDidMount 中进行提取,而不是在 componentDidUpdate 中进行提取,因此 OFC 重新安装它会获取数据。 感谢@DrewReese 的回复。我不认为这应该是一个问题,因为我在另一个页面中使用相同的QueryApolloQuery,其中数据实际上是从查询返回的并且它的行为正常,即加载是true,然后是false。我还在ApolloQuery 中记录了上面的if(loading) loading。这意味着在每次更改时我都会到达那里,但不知何故 ApolloQuery 并没有进行网络调用。我已经编辑并更新了问题。 【参考方案1】:

以防有人最终提出这个问题。深入研究这个问题,我发现react-apollo 中的Query 忽略了fetchPolicy: network-only or no-cache 在这里详细讨论的https://github.com/apollographql/react-apollo/issues/556。由于遇到此问题的人和没有遇到此问题的人不一致,因此已关闭。

我们解决这个问题的方法是通过返回 refetch 和数据并且在触发时它没有再次发送网络调用,我们调用了 refetch 并且它再次强制发送调用。

【讨论】:

以上是关于Apollo 加载在道具更改时总是错误的的主要内容,如果未能解决你的问题,请参考以下文章

使用 graphql 将道具传递给高阶组件时出现 React-apollo Typescript 错误

Apollo:在订阅更新时更新 React 道具?

React Apollo MockProvider 总是加载,从不提供数据

如何检测何时加载通过道具提供的图像并更改 React 中的状态?

如何使用 NestJS GraphQL 实现 NuxtJS Apollo

使用 Apollo 执行突变后如何更新单独的组件道具