使用 Apollo 查询闪烁
Flickering with Apollo Queries
我们在我们的电子商务网站中广泛使用 Apollo GraphQl,当路线改变时,我遇到了一些不需要的闪烁问题。
我的 ProductTypeFilter
组件包含在 Router
和 Query
组件中。 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
,这会引入不需要的 "flickering".
这只会在用户第一次访问产品类型时发生,这是 Apollo 缓存第二次找到 query
和 variables
的相同组合并呈现 ProductTypeFilter
立即。
我不能使用 state
,因为在渲染函数中不允许调用 setState
。唯一似乎有效的是引入一个全局变量,用于渲染并在新数据到达时更新:
let previousFilters = undefined
...
if (!error && previousFilters && !productFilters) {
productFilters = previousFilters
}
if (error || productFilters) {
return null
}
previousFilters = productFilters
return <ProductTypeFilter productFilters={productFilters} />
有没有更好的不让我起鸡皮疙瘩的?
Apollo 将重新获取您的查询,每次安装该组件时将加载设置为 true 和 return 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
这样您将在第一次加载时看到加载指示器或空值,但如果数据已缓存,您会立即看到数据 - 不会闪烁。
我们在我们的电子商务网站中广泛使用 Apollo GraphQl,当路线改变时,我遇到了一些不需要的闪烁问题。
我的 ProductTypeFilter
组件包含在 Router
和 Query
组件中。 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
,这会引入不需要的 "flickering".
这只会在用户第一次访问产品类型时发生,这是 Apollo 缓存第二次找到 query
和 variables
的相同组合并呈现 ProductTypeFilter
立即。
我不能使用 state
,因为在渲染函数中不允许调用 setState
。唯一似乎有效的是引入一个全局变量,用于渲染并在新数据到达时更新:
let previousFilters = undefined
...
if (!error && previousFilters && !productFilters) {
productFilters = previousFilters
}
if (error || productFilters) {
return null
}
previousFilters = productFilters
return <ProductTypeFilter productFilters={productFilters} />
有没有更好的不让我起鸡皮疙瘩的?
Apollo 将重新获取您的查询,每次安装该组件时将加载设置为 true 和 return 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
这样您将在第一次加载时看到加载指示器或空值,但如果数据已缓存,您会立即看到数据 - 不会闪烁。