Apollo 查询闪烁

Sve*_*ven 2 reactjs react-apollo

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

我的ProductTypeFilter组件被包裹在RouterandQuery组件中。使用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>
)
Run Code Online (Sandbox Code Playgroud)

null渲染时间很短,当数据到达时就会ProductTypeFilter渲染。这按预期工作。

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

这种情况仅在用户第一次访问产品类型时发生,当 Apollo 缓存第二次找到相同的query和组合variablesProductTypeFilter立即呈现时。

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

let previousFilters = undefined

...

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

previousFilters = productFilters

return <ProductTypeFilter productFilters={productFilters} />
Run Code Online (Sandbox Code Playgroud)

有没有更好的不会让我起鸡皮疙瘩的?

Jon*_*win 7

Apollo 将重新获取您的查询,将加载设置为 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 
Run Code Online (Sandbox Code Playgroud)

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