使用阿波罗查询闪烁

时间:2019-01-20 17:57:34

标签: reactjs react-apollo

我们在电子商务网站中广泛使用了Apollo GraphQl,当路线改变时,我遇到一些不必要的闪烁问题。

我的ProductTypeFilter组件包装在RouterQuery组件中。 Query使用来自路由的信息作为其变量,在本示例中为productTypeId

export const ProductTypeFilterContainer = () => (
  <Router>
    {({ query: { productTypeId } }) => (
      <Query query={GET_PRODUCT_FILTERS} variables={{ productTypeId }}>
        {({ error, loading, data: { productFilters } }) => {
          if (loading || error) {
            return null
          }
          return <ProductTypeFilter productFilters={productFilters} />
        }}
      </Query>
    )}
  </Router>
)

null在短时间内被渲染,并且当数据到达时ProductTypeFilter被渲染。这可以按预期工作。

但是,当用户导航到其他产品类型时,ProductTypeFilter将被卸载,然后使用新数据重新装载。只要查询加载,就会呈现 null,这确实会引入不必要的“闪烁”

这仅在用户第一次访问产品类型时发生,而这是第二次Apollo缓存找到queryvariables的相同组合并立即呈现ProductTypeFilter时。

我不能使用state,因为在渲染函数中不允许调用setState。似乎唯一有效的方法是引入一个全局变量,该变量用于呈现并在新数据到达时进行更新:

let previousFilters = undefined

...

if (!error && previousFilters && !productFilters) {
  productFilters = previousFilters
}
if (error || productFilters) {
  return null
}

previousFilters = productFilters

return <ProductTypeFilter productFilters={productFilters} />

有没有能让我鸡皮ump更好的东西?

1 个答案:

答案 0 :(得分:1)

Apollo将重新获取查询,将loading设置为true,并在每次安装该组件时返回null。

尽管(如果您具有Apollo缓存设置)它已经将数据存储在缓存中,它仍会执行此操作。

我建议像下面的伪代码那样对您的代码重新排序:

// it's a good idea to let your users know if something goes wrong
if(error) return ErrorMessage 

// note it's before loading
if(data) return ProductTypeFilter

// it's a good idea to let your users know there is some activity
if(loading) return LoadingIndicator 

这样,您将看到加载指示符,或者在第一次加载时为null,但是如果已缓存,则立即看到数据-不闪烁。