RelayJS 无限滚动
Posted
技术标签:
【中文标题】RelayJS 无限滚动【英文标题】:RelayJS infinite scroll 【发布时间】:2017-01-25 12:43:32 【问题描述】:我正在尝试在我的 React-Relay 前端进行无限滚动分页,但没有成功。
此刻,我有了这个 React 组件……
class List extends Component
state = loading: false ;
componentDidMount()
window.onscroll = () =>
if (!this.state.loading
&& (window.innerHeight + window.scrollY)
>= document.body.offsetHeight)
this.setState(loading: true, () =>
this.props.relay.setVariables(
count: this.props.relay.variables.count + 5
, (readyState) =>
if (readyState.done)
this.setState( loading: false );
);
);
render()
return (
<div>
this.props.viewer.products.edges.map(function(product, i)
return (<Item key=i product=product.node />);
)
</div>
);
;
...包裹在中继容器中
export default Relay.createContainer(List,
initialVariables:
count: 5
,
fragments:
viewer: () => Relay.QL`
fragment on Viewer
products(first: $count)
total
edges
node
$Item.getFragment('product')
`,
);
这背后的逻辑似乎很简单。如果您到达某个 scrollY
位置,请将新的增量值设置为 count
变量,这会扩展您的边列表。
但是这个概念会导致一种情况,一开始我在数据库中查询前 5 条记录,但最近我不断滚动查询 N+5 条记录。最后我会在数据库中查询整个表(数千条记录)!这是非常不可接受的。
所以我正在尝试实现cursors
,但我不知道如何从连接中获取数据并扩展结果。这种方法返回给我一个 “分页” 列表。
另外,当我向下滚动时,上面的代码给了我这个错误
resolveImmediate.js?39d8:27 Uncaught Invariant Violation: performUpdateIfNecessary: Unexpected batch number (current 19, pending 18)
我将非常感谢任何帮助或示例!
【问题讨论】:
【参考方案1】:问题解决了!
关于我每次滚动一次又一次地获取 N+5 记录的问题,Relay 似乎非常智能,因为它通过查询 cursor
和管理自动“分页”我的连接我的连接中的after
arg。
在我的后端 graphql-sequelize
的帮助下,它只是变成了这个查询
SELECT ... FROM product ORDER BY product.id ASC LIMIT 5 OFFSET 10
这实际上解决了我关于性能的第一个问题。 :)
所以我的Relay.QL
查询已经转译成这个
query ListPage_ViewerRelayQL($id_0:ID!)
node(id:$id_0)
...F1
fragment F0 on Product
id,
title,
price
fragment F1 on Viewer
_products4tSFq4:products(after:"YXJyYXljb25uZWN0aW9uJDUkNA==",first:5)
edges
cursor,
node
id,
...F0
,
pageInfo
hasNextPage,
hasPreviousPage
,
id
当我在我的 GraphQL 后端运行这个查询时,它返回了空结果
"data":
"node": null
然后我立即意识到问题出在哪里以及为什么我的 Relay 崩溃了。
问题在于重新获取查看器。我没有正确实现nodeDefinitions
,当查看器ID
点击idFetcher
和typeResolver
时,它失败并返回null
。之后在客户端,Relay 无法完成我连接的重新获取并崩溃了!
经过小修和后端修复,我的无限滚动就像一个魅力! :)
【讨论】:
不明白您是如何将 N+5 的问题转为正常的,而“正常”分页具有固定数量的数据,可以连接每一轮,这样效率更高。以上是关于RelayJS 无限滚动的主要内容,如果未能解决你的问题,请参考以下文章